Setting registers
RISC-V has an li instruction, short for ‘load immediate’.
It essentially writes a constant value to a register, for example, sets the
value of the x5 register to 42.
Syntax
We can use the li instruction like this:
li <register>, <immediate value>
<register> needs to be a valid register name, and <immediate value> needs to
be a valid immediate value (a constant integer).
Example
If we wanted to load the value 42 into register x5, we would write:
li x5, 42
Now, the value of x5 is 42 - you can see this by using a simulator like
Creatorsim.
Pseudo-instruction
li isn’t actually an instruction! It’s what’s called a pseudo-instruction.
Basically, when the assembler sees li, it translates it into a different
instruction (or multiple instructions) that actually do the work of loading the
immediate value into the register.
For small immediate values (like 42), the assembler translates li into an
addi instruction that adds the immediate value to the zero register (x0),
which always contains 0:
addi x5, x0, 42
That means that we could also write:
addi x5, x0, 42
…instead of using li x5, 42, and it would have the same effect.
Our full code
So, going back to our original example of exiting a program, we can now write:
.text
main:
li x5, 42 # Load the value 42 into register x5
stop:
li a7, 10 # Load the exit system call number into register a7
ecall # Make the system call to exit the program
If you run this program, you will see that the register x5 contains the value
42, and the program exits cleanly!