sw
sw
rs2, off(rs1)
mem[rs1 + off] = rs2
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

sw does the reverse of lw: it writes a value from a register out to memory. The name is short for store word (a word being a 32-bit value). If loads are how data comes in from memory to be worked on, stores are how results go back out — the two halves of RISC-V's load-compute-store cycle, since arithmetic only ever happens in registers.

The form is sw rs2, offset(rs1). Read it carefully, because the order is the opposite of what you might expect: the first register, rs2, is the *source* holding the value to write; the second part, offset(rs1), gives the *destination* address in memory (the address in base register rs1 plus a small constant offset — the same addressing form lw uses). So sw t1, 0(t0) takes the value in t1 and writes it to the address held in t0.

Notice that sw changes no register at all — its effect lands entirely in memory. That is unusual; almost every other instruction writes a register. Here the result is the updated memory slot.

Stores are how you save results into arrays and variables, and how a function tucks values away into its scratch space on the stack. A store overwrites all 4 bytes at the target address. The example writes 99 into a labeled spot in memory, replacing whatever was there; unlike a register, memory keeps that value until something stores over it again.

la t0, slot
li t1, 99
sw t1, 0(t0)   # memory at slot now holds 99