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

LC-3 ISA: memory, registers, operate and data movement instructions

The LC-3's memory layout, registers and condition codes; the ADD/AND/NOT and LD/LDI/LDR/LEA/ST/STI/STR instructions, addressing modes and encoding and decoding 16-bit machine code by hand.

instruction set architecture (ISA)opcodeoperate instructiondata movement instructionimmediatesign extensionaddressing modePC-relativeindirectbase+offsetcondition codes (N, Z, P)register fileword-addressableeffective address

Weeks 7 and 8 are the center of the course: the instruction set (ISA) of the LC-3. Everything you have learned so far comes together here: 2’s complement (offsets), sign extension (imm5), the decoder (opcode), mux and register (data path), the instruction cycle (phases). On this page you see the structure of the LC-3, the operate instructions that do calculations, and the data movement instructions that carry data between memory and registers. Branches and loops are in week 8.

Question types on the exam: translate an instruction into 16-bit machine code (encode), translate a hex value into an instruction (decode), compute the effective address, trace a short program and write the register values and condition codes.

The structure of the LC-3

ItemIn the LC-3
Memory2162^{16} = 65536 locations, each 16 bits (word-addressable)
General-purpose registersR0-R7, each 16 bits
Instruction lengthEvery instruction is exactly 16 bits
OpcodeIR[15:12], 4 bits → 16 values (15 instructions + 1 reserved)
Condition codesN, Z, P (exactly one is 1 at any moment)
Data type16-bit 2’s complement integer
Special registersPC, IR, MAR, MDR, PSR

User programs usually start at x3000. x0000-x00FF is the trap vector table, xFE00 and above are the device registers (week 6).

Condition codes

Every instruction that writes a value into a register (ADD, AND, NOT, LD, LDI, LDR) sets one of three bits to 1 according to the value written:

Value writtenNZP
negative (bit 15 = 1)100
zero010
positive001

Instructions that write to memory (ST, STI, STR) and branch instructions do not change the condition codes. In week 8 the BR instruction will decide by looking at exactly these bits.

PITFALL · LEA and the condition codes. In the 2nd edition of the textbook (the book of this course) LEA also sets the condition codes; in the 3rd edition it does not. If you see a BR right after an LEA in the exam, pay attention to which rule the instructor uses; the safest thing is to put the instruction that actually writes the value before the BR.

Opcode table

OpcodeInstructionType
0001ADDoperate
0101ANDoperate
1001NOToperate
0010LDdata movement (PC-relative)
1010LDIdata movement (indirect)
0110LDRdata movement (base+offset)
1110LEAaddress computation
0011STdata movement (PC-relative)
1011STIdata movement (indirect)
0111STRdata movement (base+offset)
0000BRcontrol
1100JMP / RETcontrol
0100JSR / JSRRcontrol (subroutine)
1111TRAPcontrol (operating system)
1000RTIcontrol (return from interrupt)
1101reserved

Operate instructions: ADD, AND, NOT

ADD and AND have two forms. Bit 5 tells which one it is.

register mode:   op  | DR  | SR1 | 0 | 00 | SR2
                 15-12 11-9  8-6   5   4-3  2-0
immediate mode:  op  | DR  | SR1 | 1 | imm5
                 15-12 11-9  8-6   5   4-0
NOT:             1001| DR  | SR  | 111111
  • ADD R5, R1, R3: R5 ← R1 + R3.
  • ADD R3, R1, #-4: R3 ← R1 + SEXT(imm5). imm5 = -4 = 11100, extended to 16 bits as 1111 1111 1111 1100.
  • NOT R1, R1: flips every bit of R1.

The range of imm5 is -16..+15. If you need a larger constant, you have to put it in memory with .FILL and load it with LD.

Encoding example

AND R4, R3, #15:

0101 | 100 | 011 | 1 | 01111
AND    R4    R3    imm  +15
0101 1000 1110 1111 = x58EF

Ready-made patterns

JobInstructionWhy
R1 = 0AND R1, R1, #0Anything AND 0 = 0
R2 = R1ADD R2, R1, #0+0 copies
R2 = 2·R2ADD R2, R2, R2Adding to itself = shift left
R3 = -R2NOT R3, R2 + ADD R3, R3, #12’s complement
R3 = R1 OR R2NOT R1, NOT R2, AND, NOTDeMorgan

The result of NOT alone is −x−1-x - 1: NOT 7 = -8. Do not forget to add +1.

Addressing modes

Where can an operand be? In the LC-3 there are five answers:

ModeWhere is the operand?Instructions
Registerin a registerADD R1, R2, R3
Immediateinside the instructionADD R1, R1, #5
PC-relativeM[PC + offset9]LD, ST
IndirectM[M[PC + offset9]]LDI, STI
Base+offsetM[BaseR + offset6]LDR, STR

LEA also computes PC + offset9 but does not read memory; it puts the address itself in the register.

PC-relative: LD and ST

LD/ST:  op | DR/SR | PCoffset9
address = (incremented PC) + SEXT(PCoffset9)

The PC is used in its incremented form. If the instruction is at x3010, when FETCH finishes PC = x3011. The offset is added to this. The offset is 9 bits, range -256..+255: an instruction can access about 256 locations near itself.

LD R2, #-5 at x3010: address = x3011 - 5 = x300C.

0010 | 010 | 1 1111 1011 = x25FB
LD     R2    -5

PITFALL · adding the offset to the instruction’s own address. Whoever writes x3010 + (-5) = x300B loses points. The PC had already been incremented by one in FETCH: x3011 + (-5) = x300C.

Indirect: LDI and STI

An address is stored in memory. First that address is read, then the data at that address.

LDI R3, #2 (at x3000)
1) x3001 + 2 = x3003       M[x3003] = x4000   (this is a pointer)
2) M[x4000] = x0042  →  R3 = x0042

This is the way to reach far addresses (for example the device registers at xFE00).

Base+offset: LDR and STR

LDR/STR:  op | DR/SR | BaseR | offset6
address = BaseR + SEXT(offset6)      range -32..+31

Because the base register is 16 bits, any place in memory can be reached. Arrays, the stack and pointers work with this mode (you will see them in the C weeks).

With STR R2, R5, #-1 and R5 = x4001, R2 = x00AA → M[x4000] = x00AA.

LEA: load the address

LEA R1, ARR → R1 ← the address of ARR. Memory is not read. To get the starting address of an array, use LEA, then access the elements with LDR:

        LEA  R1, ARR       ; R1 = x3005 (the address of ARR)
        LDR  R2, R1, #2    ; R2 = ARR[2] = 10
        LDR  R3, R1, #0    ; R3 = ARR[0] = 7
        ADD  R4, R2, R3    ; R4 = 17
        HALT
ARR     .FILL #7
        .FILL #-2
        .FILL #10

Decode recipe

  1. Expand the hex to 16 bits.
  2. The first 4 bits are the opcode, look at the table.
  3. According to the format of the opcode, split the remaining 12 bits into fields.
  4. If there is an offset, sign-extend it, and if an address is needed, add it to the incremented PC.

Example: x2A10, at address x3100.

0010 101 0 0001 0000
LD   R5  PCoffset9 = 0 0001 0000 = +16
address = x3101 + 16 = x3101 + x10 = x3111
→ LD R5, x3111    (R5 ← M[x3111])

Example: x7F3F.

0111 111 100 111111
STR  R7  R4  offset6 = 111111 = -1
→ STR R7, R4, #-1    (M[R4 - 1] ← R7)

Worked trace

        .ORIG x3000
        LD   R1, A        ; R1 = 13
        LD   R2, B        ; R2 = -6
        ADD  R3, R1, R2   ; R3 = 7
        AND  R4, R3, #7   ; R4 = 7
        NOT  R5, R4       ; R5 = -8
        ST   R3, C        ; M[C] = 7
        HALT
A       .FILL #13
B       .FILL #-6
C       .BLKW 1
        .END

The machine code the assembler produced:

x3000  x2206   LD  R1, A      (x3001 + 6 = x3007 = A)
x3001  x2406   LD  R2, B      (x3002 + 6 = x3008 = B)
x3002  x1642   ADD R3, R1, R2
x3003  x58E7   AND R4, R3, #7
x3004  x9B3F   NOT R5, R4
x3005  x3603   ST  R3, C      (x3006 + 3 = x3009 = C)
x3006  xF025   HALT
x3007  x000D   A = 13
x3008  xFFFA   B = -6
x3009  x0000   C

Result: R3 = 7, R4 = 7, R5 = xFFF8 (-8), M[x3009] = 7. The last instruction that set the CC is NOT (R5 is negative) → N. ST did not change the CC.

Common mistakes

Wrong ideaThe truth
The offset is added to the instruction’s own addressTo the incremented PC (address + 1)
The imm5 range is 0..31-16..+15, sign-extended
LEA reads from memoryIt only computes the address
LDI = LDLDI reads twice: first the address, then the data
The LDR offset is 9 bits6 bits, -32..+31
ST sets the condition codesInstructions that write to memory do not touch the CC
NOT x = -xNOT x = -x - 1; add +1 for -x
Bit 5 = 0 → immediateBit 5 = 1 is immediate, 0 is register

Test yourself

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

Question 1easy

Encode ADD R3, R1, #-4 as a 16-bit LC-3 machine instruction in hex.

Show answer
x167C

Format: 0001 | DR | SR1 | 1 | imm5. DR = R3 = 011, SR1 = R1 = 001, bit 5 = 1 (immediate), imm5 = -4 = 11100.
0001 011 001 1 11100 → 0001 0110 0111 1100 = x167C.

Question 2easy

Decode the LC-3 instruction x1A43.

Show answer
ADD R5, R1, R3

x1A43 = 0001 1010 0100 0011. Opcode 0001 = ADD. DR = bits 11:9 = 101 = R5. SR1 = bits 8:6 = 001 = R1. Bit 5 = 0 → register mode, SR2 = bits 2:0 = 011 = R3.

Question 3easy

Decode x927F.

Show answer
NOT R1, R1

1001 0010 0111 1111. Opcode 1001 = NOT. DR = 001, SR = 001, bits 5:0 = 111111 (all 1s in NOT). R1 ← NOT R1.

Question 4easy

What is the range of the immediate value in ADD DR, SR1, #imm5?

Show answer
-16 to +15

imm5 is a 5-bit 2's complement value: −24…24−1-2^4 \ldots 2^4 - 1. At run time it is sign-extended to 16 bits. If you write #16 or #-17 the assembler gives an error.

Question 5medium

The instruction LD R2, LABEL is at address x3010 and its PCoffset9 is -5. Which address is read, and what is the machine code?

Show answer
x300C, x25FB

Address = incremented PC + SEXT(offset) = x3011 + (-5) = x300C. The PC was incremented in FETCH, the offset is added to x3011, not x3010.
Code: 0010 | 010 | 1 1111 1011 → 0010 0101 1111 1011 = x25FB.

Question 6medium

LEA R0, #10 is at address x3005. What value is placed in R0? Does LEA access memory?

Show answer
x3010, no

LEA computes the address and puts the address itself in R0: x3006 + 10 = x3006 + xA = x3010. It does not read memory. The name 'Load Effective Address' comes from this.

Question 7medium

Before execution, M[x3003] = x4000 and M[x4000] = x0042. What does LDI R3, #2 at address x3000 load into R3?

Show answer
x0042

LDI reads in two steps. 1) x3001 + 2 = x3003; M[x3003] = x4000, this is an address. 2) M[x4000] = x0042 → R3. The condition code becomes P.

Question 8easy

R6 = x5000 and M[x5004] = xFFFE. After LDR R1, R6, #4, what are R1 and the condition codes?

Show answer
R1 = xFFFE, N

Address = R6 + SEXT(offset6) = x5000 + 4 = x5004. R1 ← M[x5004] = xFFFE = -2. Because it is negative, N = 1.

Question 9medium

Write three LC-3 instructions that compute R3 = R1 - R2 (R1 and R2 must not change).

Show answer
NOT R3, R2; ADD R3, R3, #1; ADD R3, R1, R3

There is no SUB in the LC-3. 2's complement: −R2=NOT(R2)+1-R2 = \text{NOT}(R2) + 1. First R3 ← NOT R2, then R3 ← R3 + 1 (now -R2), finally R3 ← R1 + R3. Example: R1 = 20, R2 = 27 → R3 = -7 = xFFF9, CC = N.

Question 10medium

What are R3, R4, R5 and the memory location C after this program runs?

        .ORIG x3000
        LD   R1, A
        LD   R2, B
        ADD  R3, R1, R2
        AND  R4, R3, #7
        NOT  R5, R4
        ST   R3, C
        HALT
A       .FILL #13
B       .FILL #-6
C       .BLKW 1
        .END
Show answer
R3 = 7, R4 = 7, R5 = -8 (xFFF8), C = 7

R1 = 13, R2 = -6. R3 = 13 + (-6) = 7 = 0000 0000 0000 0111.
R4 = 7 AND 7 = 7 (low 3 bits). R5 = NOT 7 = 1111 1111 1111 1000 = xFFF8 = -8 (NOT x = -x - 1).
ST R3, C → M[C] = 7. ST does not change the condition codes.

Question 11medium

Which of these instructions set the condition codes: ADD, ST, LDR, STR, NOT, AND?

Show answer
ADD, LDR, NOT, AND

The condition codes are set by instructions that WRITE a value into a register: ADD, AND, NOT, LD, LDI, LDR (and LEA in the 2nd edition of the textbook). ST, STI, STR, which write to memory, and branch instructions do not change the CC.

Question 12hard

Decode xE1FD located at address x3050. What does it put in R0?

Show answer
LEA R0, offset -3 → R0 = x304E

1110 0001 1111 1101: opcode 1110 = LEA, DR = 000 = R0, PCoffset9 = 1 1111 1101 = -3.
R0 = x3051 + (-3) = x304E.

Verification: Every encoding, decoding and trace was produced on the LC-3 assembler + simulator we wrote ourselves (verify/SEN2201/lc3.mjs); the register values, condition codes and memory contents were taken from there (verify/SEN2201/07.mjs). The condition code behavior of LEA follows the 2nd edition of the textbook.

Review card

Memory 2^16 × 16 bits, word-addressable | R0-R7 (16 bits) | PC, IR | CC: N Z P (exactly one is 1) Opcode IR[15:12]: ADD 0001 AND 0101 NOT 1001 LD 0010 LDI 1010 LDR 0110 LEA 1110 ST 0011 STI 1011 STR 0111 BR 0000 JMP 1100 JSR 0100 TRAP 1111 RTI 1000 ADD/AND: op DR SR1 0 00 SR2 | op DR SR1 1 imm5 (-16..15, SEXT) NOT: 1001 DR SR 111111 LD/LDI/LEA/ST/STI: op R PCoffset9 -> address = (PC+1) + SEXT(off9), range -256..255 LDR/STR: op R BaseR off6 -> address = BaseR + SEXT(off6), range -32..31 LD: R <- M[PC+off] | LDI: R <- M[M[PC+off]] | LDR: R <- M[Base+off] | LEA: R <- PC+off (no memory) ST: M[PC+off] <- R | STI: M[M[PC+off]] <- R | STR: M[Base+off] <- R Sets the CC: ADD AND NOT LD LDI LDR (LEA yes in the 2nd edition) | ST/STI/STR/BR no Clear: AND R,R,#0 | Copy: ADD R2,R1,#0 | -x: NOT, ADD #1 | OR: NOT-AND-NOT