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
.ENDLDI 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
.ENDUse 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