Memory & Data

LDR, STR, LDI & STI

Base+offset and indirect addressing modes.

The Problem with PC-Relative

LD and ST use a 9-bit offset, giving a range of only -256 to +255 from the PC. What if your data is further away?

The LC-3 provides two solutions: base+offset and indirect addressing.

LDR and STR — Base+Offset

LDR DR, BaseR, #offset6 — Load from memory[BaseR + offset] STR SR, BaseR, #offset6 — Store to memory[BaseR + offset]

The base register holds a full 16-bit address, so you can reach any memory location. The 6-bit offset gives a range of -32 to +31 from the base.

.ORIG x3000
LEA R1, ARRAY      ; R1 = address of ARRAY
LDR R0, R1, #0     ; R0 = ARRAY[0] = 10
LDR R2, R1, #1     ; R2 = ARRAY[1] = 20
LDR R3, R1, #2     ; R3 = ARRAY[2] = 30
ADD R0, R0, R2     ; R0 = 10 + 20
ADD R0, R0, R3     ; R0 = 30 + 30 = 60
HALT
ARRAY .FILL #10
      .FILL #20
      .FILL #30
.END

LDI and STI — Indirect Addressing

LDI DR, LABEL — The value at LABEL is treated as an address, and the data at *that* address is loaded into DR. It's a double dereference: DR = memory[memory[LABEL]]. STI SR, LABEL — Similarly, stores SR to the address pointed to by the value at LABEL.

Think of it as following a pointer.

.ORIG x3000
LDI R0, PTR     ; R0 = memory[memory[PTR]] = memory[x4000]
HALT
PTR .FILL x4000  ; PTR contains the address x4000
.END

Use LDR/STR when you have the base address in a register (great for arrays). Use LDI/STI when you need to follow a pointer stored in memory.

Exercise

Write a program that uses LDR to sum all 4 elements of an array and prints the sum as an ASCII digit. The array contains {1, 2, 3, 4} so the sum is 10... let's use {1, 2, 3, 1} for a sum of 7.

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