Control Flow

Branching (BR)

Conditional and unconditional branches using condition codes.

Condition Codes

Every instruction that writes to a register sets the condition codes:

  • N = 1 if the result is negative
  • Z = 1 if the result is zero
  • P = 1 if the result is positive
  • Exactly one of N, Z, P is set at any time. These instructions set CC: ADD, AND, NOT, LD, LDI, LDR, LEA.

    The BR Instruction

    BR[n][z][p] LABEL — Branch to LABEL if the specified condition codes are set.

    You specify which flags to check by including n, z, and/or p:

    BRn NEGATIVE    ; Branch if result was negative
    BRz ZERO        ; Branch if result was zero
    BRp POSITIVE    ; Branch if result was positive
    BRnz NOT_POS    ; Branch if negative OR zero
    BRnp NOT_ZERO   ; Branch if negative OR positive (not zero)
    BRzp NOT_NEG    ; Branch if zero OR positive (not negative)
    BRnzp ALWAYS    ; Branch always (unconditional)
    BR ALWAYS       ; Same as BRnzp — always branches

    Example: If-Else

    Here's how to implement an if-else in LC-3:

    .ORIG x3000
    LD R0, X
    ADD R0, R0, #0     ; Set CC based on R0 (important!)
    BRn IS_NEG         ; if R0 < 0, goto IS_NEG
    LEA R0, POS_MSG    ; else: print "Positive"
    PUTS
    BR DONE            ; skip the negative branch
    IS_NEG
    LEA R0, NEG_MSG    ; print "Negative"
    PUTS
    DONE
    HALT
    X .FILL #5
    POS_MSG .STRINGZ "Positive"
    NEG_MSG .STRINGZ "Negative"
    .END

    If you load a value with LD or ADD R0, R0, #0, the CC is already set. But after operations like ST, the CC is not updated. Always make sure CC reflects what you want to test before branching.

    Choosing the Right Branch

    The trick is mapping your high-level condition to a CC check:

    High-Level ConditionSetupBranch
    if (x == 0)ADD R0, R0, #0BRz
    if (x != 0)ADD R0, R0, #0BRnp
    if (x > 0)ADD R0, R0, #0BRp
    if (x < 0)ADD R0, R0, #0BRn
    if (x >= 0)ADD R0, R0, #0BRzp
    if (a == b)subtract a - bBRz
    if (a != b)subtract a - bBRnp
    if (a > b)subtract a - bBRp
    always jump(no setup needed)BRnzp or BR
    The pattern is always the same: get the value you care about into the condition codes (by doing an operation that writes to a register), then branch.
    Exercise

    Write a program that loads a number from memory. If it's zero, print "Z". If positive, print "P". If negative, print "N".

    main.asm
    1
    R0
    x00000
    R1
    x00000
    R2
    x00000
    R3
    x00000
    R4
    x00000
    R5
    x00000
    R6
    x00000
    R7
    x00000
    PCx3000
    CC
    NZP