SEN2201 · Week 8 · ISA Overview (Memory organization and registers)

LC-3 control instructions: BR, JMP, TRAP and loops

The BR instruction that looks at the condition codes, offset calculation, JMP/RET and TRAP; counter and sentinel loops, the if/else pattern, and reading and tracing a program from hex machine code.

control instructionconditional branchunconditional branchBRn z p bitsPCoffset9JMPRETTRAPtrap vectorloopcounter-controlled loopsentinelcondition codes

Last week the instructions always ran in order: every FETCH incremented the PC by one. Real programs, however, make decisions (if) and repeat (loops). For this there are control instructions: by writing a new value into the PC, they change the next instruction. In the LC-3 these are BR, JMP, JSR, TRAP and RTI. On this page you see BR, JMP and TRAP, and then the loop and if patterns built with them.

Exam questions: encode or decode a BR (offset calculation), decode and trace a program given in hex, find how many times a loop runs and the register values at the end.

BR: conditional branch

0000 | n | z | p | PCoffset9
15-12  11  10   9   8-0

BR looks at the condition codes. If one of the bits that is 1 in the instruction matches the current condition code, it branches: PC ← (incremented PC) + SEXT(PCoffset9). If it does not match, it does nothing, and the program moves on to the next instruction.

Assemblyn z pWhen does it branch?
BRn1 0 0the last value is negative
BRz0 1 0the last value is zero
BRp0 0 1the last value is positive
BRnz1 1 0≤ 0
BRzp0 1 1≥ 0
BRnp1 0 1≠ 0
BR / BRnzp1 1 1always
(000)0 0 0never (NOP)

TIP · What does BR look at? BR looks at the result of the last instruction that wrote to a register for the condition code. In between there can be instructions that do not change the CC, like ST, STR, BR; they do not count. If you want to test a register, first write it somewhere: ADD R1, R1, #0 sets the CC according to R1.

Offset calculation

PCoffset9=target−(address of the BR+1)\text{PCoffset9} = \text{target} - (\text{address of the BR} + 1)

The range is -256..+255. When branching backward (to the start of a loop), the offset is negative.

Encoding example: BRn LOOP at x3008, LOOP = x3002.

offset = x3002 - x3009 = -7
-7 (9 bits) = 1 1111 1001
0000 100 111111001 = x09F9

Decoding example: x0BFC, at x3020.

0000 101 111111100
n=1 z=0 p=1  → BRnp
offset = 1 1111 1100 = -4
target = x3021 - 4 = x301D

JMP and RET

1100 | 000 | BaseR | 000000

PC ← BaseR. Because the target is in a register, it can jump anywhere in memory (BR reaches only ±256). JMP R2 = xC080. RET is an alias of JMP R7 (xC1C0); it is used to return from a subroutine or a TRAP routine.

TRAP

1111 | 0000 | trapvect8
  1. R7 ← PC (the incremented PC, the return address).
  2. PC ← M[ZEXT(trapvect8)]: take the address of the routine from the trap vector table between x0000-x00FF.
CodeAliasJob
xF020GETCread a character → R0
xF021OUTwrite R0
xF022PUTSwrite the string at the address in R0
xF023INprompt + read a character + echo → R0
xF025HALTstop

Loop patterns

Counter loop (counter-controlled)

How many times to loop is known from the start. The counter is kept in a register, decreased in every round, and the loop exits when it reaches zero.

Worked example: multiplication. There is no MUL in the LC-3; 6 × 4 = 6 + 6 + 6 + 6.

        .ORIG x3000
        AND  R3, R3, #0    ; R3 = 0 (result)
        LD   R1, X         ; R1 = 6
        LD   R2, Y         ; R2 = 4 (counter)
LOOP    ADD  R3, R3, R1    ; R3 += 6
        ADD  R2, R2, #-1   ; counter--
        BRp  LOOP          ; repeat if counter > 0
        HALT
X       .FILL #6
Y       .FILL #4
        .END
round R3    R2   CC   BRp
 1     6     3    P   loop back
 2    12     2    P   loop back
 3    18     1    P   loop back
 4    24     0    Z   fall through

The result is R3 = 24. The machine code:

x3000 x56E0  AND R3, R3, #0
x3001 x2205  LD  R1, X       (x3002 + 5 = x3007)
x3002 x2405  LD  R2, Y       (x3003 + 5 = x3008)
x3003 x16C1  ADD R3, R3, R1
x3004 x14BF  ADD R2, R2, #-1
x3005 x03FD  BRp x3003       (x3006 - 3)
x3006 xF025  HALT

PITFALL · one round too many. If you write BRzp instead of BRp, it also loops back when R2 = 0, runs 5 rounds, and the result is 30. If you want the counter to end at 0, use BRp.

Sentinel loop

The number of elements is not known; at the end of the list there is a special value (the sentinel, usually 0). Each element is loaded, and if it is the sentinel the loop exits.

Worked example: count the negatives.

        AND  R2, R2, #0     ; counter = 0
        LEA  R1, DATA       ; R1 = address of the array
LOOP    LDR  R3, R1, #0     ; R3 = *R1, the CC is set
        BRz  DONE           ; 0 → finished
        BRp  NEXT           ; positive → do not count
        ADD  R2, R2, #1     ; negative → count
NEXT    ADD  R1, R1, #1     ; next element
        BRnzp LOOP
DONE    ST   R2, RESULT
        HALT
RESULT  .BLKW 1
DATA    .FILL #5
        .FILL #-3
        .FILL #-8
        .FILL #2
        .FILL #-1
        .FILL #0

The result is RESULT = 3. BRz and BRp back to back look at the same CC, because BR does not change the CC.

if and if/else

The pattern: skip with the opposite of the condition. To write “if x is negative do this”, you write “if x is not negative (zp) skip”.

Absolute value:

        LD   R1, V          ; CC = the sign of V
        BRzp DONE           ; skip if not negative
        NOT  R1, R1         ; R1 = -R1
        ADD  R1, R1, #1
DONE    ST   R1, V
        HALT
V       .FILL #-25

The result is V = 25.

if/else: the larger of two numbers.

        LD   R1, A
        LD   R2, B
        NOT  R3, R2
        ADD  R3, R3, #1
        ADD  R3, R1, R3     ; R3 = A - B, the CC is set
        BRn  BBIG           ; if A < B go to the else part
        ADD  R4, R1, #0     ; then: R4 = A
        BRnzp END           ; skip the else
BBIG    ADD  R4, R2, #0     ; else: R4 = B
END     HALT
A       .FILL #-4
B       .FILL #9

The result is R4 = 9. Without the unconditional BRnzp END at the end of the then block, the program would fall into the else block too.

Reading a program from hex

In the exam sometimes only the machine code is given. The recipe:

  1. Expand each word to 16 bits, look at the opcode.
  2. Write the instruction in assembly; compute the BR targets with addresses.
  3. Set up a trace table (registers, CC, branches).
x3000 x5020  AND R0, R0, #0
x3001 x1225  ADD R1, R0, #5
x3002 x1001  ADD R0, R0, R1
x3003 x127E  ADD R1, R1, #-2
x3004 x03FD  BRp x3002
x3005 xF025  HALT

R1: 5 → 3 → 1 → -1     R0: 5 → 8 → 9     result R0 = 9

Common mistakes

Wrong ideaThe truth
Offset = target - BR addresstarget - (BR address + 1)
BR produces its own CCBR looks at the CC of the last register write
BRzp and BRp loop the same number of timesBRzp is one round more
x0000 is an invalid instructionA BR with nzp = 000 is a NOP
JMP reaches only ±256BaseR is 16 bits, anywhere
TRAP writes the return address to the PCIt writes it to R7
For an if, branch on the condition itselfUsually skip with the opposite of the condition
BRnzp is not needed at the end of thenOtherwise the else runs too

Test yourself

Exam-style questions. Solve them on paper first, then reveal the answer.

Question 1easy

Encode BRz with PCoffset9 = -6 in hex.

Show answer
x05FA

Format: 0000 | n z p | PCoffset9. BRz → n=0, z=1, p=0. -6 (9 bits) = 1 1111 1010.
0000 010 111111010 → 0000 0101 1111 1010 = x05FA.

Question 2easy

Decode x0E05 located at address x3010. Where does it go, and when?

Show answer
BRnzp to x3016, always

0000 111 000000101: n = z = p = 1, that is an unconditional branch (BR or BRnzp). Target = x3011 + 5 = x3016.

Question 3medium

A BRn LOOP instruction is at x3008 and LOOP is at x3002. What is the PCoffset9 and the machine code?

Show answer
-7, x09F9

offset = target - (instruction address + 1) = x3002 - x3009 = -7. -7 = 1 1111 1001.
0000 100 111111001 = 0000 1001 1111 1001 = x09F9.

Question 4medium

What does an LC-3 BR instruction with n = z = p = 0 (for example x0000) do?

Show answer
Nothing: it never branches (NOP)

BR branches if one of the bits it tests matches the condition code. If no bit is selected, it never matches. The PC advances only with the +1 in FETCH. That is why x0000 behaves like a NOP.

Question 5medium

Encode JMP R2 and RET in hex.

Show answer
xC080 and xC1C0

Format: 1100 | 000 | BaseR | 000000. JMP R2: 1100 000 010 000000 = xC080. RET is an alias of JMP R7: 1100 000 111 000000 = xC1C0. Both do PC ← BaseR.

Question 6easy

What are R3 and R2 when this program halts, and how many times is the instruction at LOOP executed?

        AND  R3, R3, #0
        LD   R1, X
        LD   R2, Y
LOOP    ADD  R3, R3, R1
        ADD  R2, R2, #-1
        BRp  LOOP
        HALT
X       .FILL #6
Y       .FILL #4
Show answer
R3 = 24, R2 = 0, 4 times

R2 is the counter (4). In each round 6 is added to R3 and R2 decreases by one. R2: 3, 2, 1 (P → loop back), 0 (Z → fall through). The loop runs 4 times: R3 = 4 × 6 = 24. This is how multiplication is done in the LC-3 (there is no MUL instruction).

Question 7medium

In the previous program, BRp is replaced by BRzp. What is R3 now?

Show answer
30

BRzp also loops back when R2 = 0. The loop runs 5 times until R2 = -1: 5 × 6 = 30. In a counter loop, the branch condition is the most common cause of running one round too many or too few.

Question 8hard

The memory starting at x3000 contains x5020, x1225, x1001, x127E, x03FD, xF025. Decode the program and give R0 when it halts.

Show answer
R0 = 9

x5020 AND R0,R0,#0 · x1225 ADD R1,R0,#5 · x1001 ADD R0,R0,R1 · x127E ADD R1,R1,#-2 · x03FD BRp x3002 · xF025 HALT.
R1 = 5 → R0 = 5, R1 = 3 → R0 = 8, R1 = 1 → R0 = 9, R1 = -1 (N) → the loop ends. R0 = 5 + 3 + 1 = 9.

Question 9medium

This program counts something in a list that ends with 0. What value is stored in RESULT?

        AND  R2, R2, #0
        LEA  R1, DATA
LOOP    LDR  R3, R1, #0
        BRz  DONE
        BRp  NEXT
        ADD  R2, R2, #1
NEXT    ADD  R1, R1, #1
        BRnzp LOOP
DONE    ST   R2, RESULT
        HALT
RESULT  .BLKW 1
DATA    .FILL #5
        .FILL #-3
        .FILL #-8
        .FILL #2
        .FILL #-1
        .FILL #0
Show answer
3

LDR loads each element and sets the CC. If it is 0, finish (sentinel), if positive, do not count, if negative, increment R2. The two BRs back to back look at the same CC, because BR does not change the CC. The negatives: -3, -8, -1 → 3.

Question 10easy

R1 = x8000. After ADD R2, R1, #0, is the following BRn taken? Why?

Show answer
Yes, x8000 is negative

ADD R2, R1, #0 copies R1 to R2 and sets the CC. x8000 = 1000 0000 0000 0000, bit 15 = 1 → -32768, N = 1. BRn branches. The standard way to test the sign of a register is to write it to itself or to another register by adding #0.

Question 11medium

TRAP x25 is located at address x3001. What value is written to R7, and what is loaded into the PC?

Show answer
R7 = x3002, PC = M[x0025]

TRAP writes the return address into R7: the incremented PC = x3002. Then trapvect8 = x25 is zero-extended and PC ← M[x0025] (the start of the service routine). The routine returns to x3002 with RET (HALT does not return, it stops the machine).

Question 12hard

A loop starts with R1 = 10. Each iteration adds 1 to R2 (initially 0), then executes ADD R1, R1, #-3 and BRzp back to the loop start. What are R2 and R1 at the end?

Show answer
R2 = 4, R1 = -2

R1: 10 → 7 (P, loop back) → 4 (loop back) → 1 (loop back) → -2 (N, fall through). The body ran 4 times: R2 = 4, R1 = -2.

Verification: All BR/JMP/TRAP encodings, offsets and program traces were produced and run on our own LC-3 assembler + simulator (verify/SEN2201/lc3.mjs); loop counts were counted instruction by instruction (verify/SEN2201/08.mjs).

Review card

BR: 0000 n z p PCoffset9 | target = (PC+1) + SEXT(off9) | branch if one of the selected bits matches the CC nzp=111 -> unconditional (BR/BRnzp) | nzp=000 -> never (NOP) offset = target - (BR address + 1). A backward branch -> negative offset The LAST instruction that wrote a register decides the CC (ADD AND NOT LD LDI LDR). BR/ST/STR do not disturb the CC JMP: 1100 000 BaseR 000000 -> PC <- BaseR | RET = JMP R7 = xC1C0 TRAP: 1111 0000 trapvect8 -> R7 <- PC+1, PC <- M[trapvect] | HALT = xF025 Counter loop: ADD R2,R2,#-1 / BRp LOOP (n times) | BRzp -> n+1 times! Sentinel loop: LDR R3,R1,#0 / BRz DONE if (x<0): write the value -> BRzp SKIP (skip with the opposite of the condition) if/else: BRx ELSE ... BRnzp END / ELSE ... / END Multiplication: repeated addition | Subtraction: NOT + 1 + ADD