lw
lyszt.net covers lw and other RISC-V instructions in more detail.
Encoding format
Description
lw copies a value from memory into a register. The 32 registers form the processor's small, fast working area. Memory sits alongside them as the large store: a long row of numbered slots that holds arrays, text and variables. A slot's number is its address. Computation takes place in registers, and data waits in memory between uses.
RISC-V does arithmetic on registers only, never directly on memory, so a value must be loaded into a register before use and stored back afterward. lw carries out the load. The name means load word, and a word is a 32-bit value, the width of one register.
The form of lw appears below. It takes the value in rs1, a register holding a memory address called the base, adds offset, a small constant, and reads the value at the resulting address into destination register rd.
lw rd, offset(rs1)
The next line loads the value 8 bytes past the address in t0.
lw t1, 8(t0)
The RISC-V manual calls RISC-V a load-store architecture: load and store instructions are the only ones that reach memory, and arithmetic instructions work on registers alone. The address space is 32 bits and byte-addressed, and the effective address of a load is register rs1 plus the sign-extended 12-bit offset. The execution environment, meaning the system the program runs in, decides whether memory holds the least significant byte first, called little-endian, or the most significant byte first, called big-endian. An access is naturally aligned when its address divides evenly by the size of the access, which is 4 bytes for a word. Naturally aligned accesses never raise an alignment error. A misaligned access behaves as the environment defines and can run very slowly.
The offset is there because items in memory sit at regular distances. A word is 4 bytes, so consecutive elements of an array lie 4 bytes apart, at offsets 0, 4, 8 and so on. la places the array's starting address in a register, and changing the offset reads the different elements. The example loads two neighbors of an array. Offset 0 gives the first value, 10, and offset 4 gives the next value, 20.
Example
.data arr: .word 10, 20 .text la t0, arr lw t1, 0(t0) # t1 = 10 lw t2, 4(t0) # t2 = 20
