The syntax of the store-word (sw
) instruction is
sw rs2, offset(rs1)
where offset is a 12 bit immediate operand.
When you write sw a1, num
you get an syntax error and the assembler fails with:
foo.s: : Assembler messages:
foo.s::13: Error: illegal operands `sw a1,num'
Perhaps the simplest way to solve this is to use the load-address (la
) pseudo-instruction:
li a1, 100
la t0, num
sw a1, 0(t0)
Since the la
instruction completely loads the address into a register we have to use 0
as offset.
The la
pseudo-instruction expands to program-counter (PC) relative addressing, i.e. check with objdump
:
00000000000100b0 <_start>:
100b0: 06400593 addi a1,zero,100
100b4: 00001297 auipc t0,0x1
100b8: 01028293 addi t0,t0,16 # 110c4 <__DATA_BEGIN__>
100bc: 00b2a023 sw a1,0(t0)
Alternatively, you can use absolute addressing:
li a1, 100
lui t0, %hi(num)
sw a1, %lo(num)(t0)
Note that the %hi()
and %lo()
assembler macros split a 32 bit address into its high 20 bits and low 12 bits parts (i.e. %hi(num) + sign_ext(%lo(num)) = num
).