Memory: load & store
Memory is a large row of numbered storage slots, and each slot holds one byte (8 bits). The number of a slot is its address. Registers are the CPU's small set of fast slots. Memory is much larger but slower, and it holds everything that does not fit in registers, such as arrays and strings. To work with a value in memory, you load it into a register, change it, and store it back.
Registers are few and memory is large. (load word) copies a word from memory into a register, and (store word) copies it back. The address is written as offset(register).
RISC-V memory is byte-addressed, so each byte has its own address in sequence. A word is 32 bits, or 4 bytes, so you advance a memory pointer by 4 to reach the next word. This is why array offsets are 0, 4, 8, and so on. On real hardware, loading a word from an address that is not a multiple of 4 can be slow or can cause a trap. This simulator permits it, but you should form the habit of keeping words aligned to 4 bytes.
lw t0, 0(a1) # t0 = memory at address a1sw t0, 4(a1) # memory at address a1+4 = t0
In offset(register), the address held in the register has the small offset number added to it. 0(a1) is the address in a1 itself, and 4(a1) is 4 bytes past it. This lets you reach nearby values without changing the base register.
| Address | Value |
|---|---|
| 0x100C | 0x00000000 |
| 0x1008 | 0x00000000 |
| 0x1004 | 0x00000000 |
| 0x1000 | 0x00000000 |
| 0x0FFC | 0x00000000 |
Registers and memory start at zero.
a0 stays the same. Only the literal offset written in the instruction increases, moving to the next target memory address.
To create memory that matches this pattern, reserve named memory in the data section with .word (one or more 32-bit values) or .space N (N blank bytes). Each word is 4 bytes, so consecutive items sit at offsets 0, 4, 8, which are the same numbers used in your store instructions.Use .word (one or more 32-bit values) or .space N (N blank bytes) to reserve named memory in the data section. Each word takes 4 bytes, so consecutive items are at offsets 0, 4, 8 and so on.
.datanums: .word 10, 20, 30, 40 # four words.textla t1, nums # t1 = address of the arrayli t2, 4 # countli t0, 0 # running sumloop:beq t2, zero, donelw t3, 0(t1) # load current elementadd t0, t0, t3 # add to sumaddi t1, t1, 4 # advance to next word (4 bytes)addi t2, t2, -1 # one fewer leftj loopdone:mv a0, t0 # print the total (100)li a7, 1ecallli a7, 10ecall
puts the address of the array in t1, t2 counts the 4 remaining elements, and t0 holds the running sum. On each pass, stops the loop when no elements remain. loads the element that t1 points to, adds it to the sum, advances the pointer by one word, and reduces the count. After all four elements (10 + 20 + 30 + 40), done prints 100.
