rd, off(rs1)rd = mem[rs1 + off]lw brings a value in from memory, so first: what is memory? The 32 registers are the processor's tiny on-hand workspace — fast, but far too few to hold much. Memory is the large store alongside them, a vast row of numbered slots that holds everything else: arrays, text, variables. The number identifying a slot is called its address. Registers are where you compute; memory is where data lives in between.
That split matters because RISC-V can only do arithmetic on registers, never directly on memory. So data must be carried in before use and carried back out after. lw is the carry-in. Its name is short for load word, where a word means a 32-bit value — the size of one register.
The form looks unusual: lw rd, offset(rs1). It reads from the address found by taking the value in rs1 (a register holding a memory address, called the base) and adding offset (a small constant). The result goes into destination register rd. So lw t1, 8(t0) loads the value sitting 8 bytes past the address in t0.
Why add an offset? Because items in memory sit at regular distances. A word is 4 bytes, so consecutive elements of an array are 4 apart — offsets 0, 4, 8, and so on. You typically get the array's starting address into a register with la, then read elements by varying the offset. The example loads two neighbours of an array: offset 0 gives the first value 10, offset 4 gives the next, 20.
.data arr: .word 10, 20 .text la t0, arr lw t1, 0(t0) # t1 = 10 lw t2, 4(t0) # t2 = 20