RISC-V¶
Intro to Instruction Set Architecture (ISA)¶
Defines the set of instructions, registers, memory access, and execution behavior for RISC-V processors.
- Arithmetic and logic operations
- Memory access: load and store
- Control flow: branches and jumps
- System calls: for I/O, etc.
Popular ISAs¶
- x86 / AMD64
- ARM
- RISC-V
- Simple, elegant, and open-source
- Flexible and extensible
Assembly Language¶
- Basic job of a CPU: execute a series of instructions.
- Basic job of a instruction: change the state of a computer.
CPU State: Assembly Registers¶
- Unlike C or Java, assembly cannot use variables
- Keep assembly/computer hardware abstract simple
- Assembly operands are registers
- Limited number of special locations/memory built directly into the CPU
- Operations can only be performed on these registers in RISC-V
- Benefit: Since registers are directly in hardware (CPU), they are very fast

Intro to RISC-V¶
Assembly Instructions¶
-
R-type
- Register-register operation, mainly for arithmetic & logic.
- Has two operands and a output.
- Cannot access main memory.
-
I-type
- Register-Immediate type.
- Has two operand (one accessed from source register, another a constant/immediate, sign-extended) and a output (saved to destination register).
- Can do arithmetic, logic and load from main memory.

RV32I R-type¶
Arithmetic¶
-
Addition: (
rd=rs1+rs2) -
Subtraction: (
rd=rs1-rs2)
Logic Operation¶
-
AND/OR/XOR: (
rd=rs1&/|/^rs2)Logically bit-wise and/or/xor the value stored in register
rs1and that ofrs2and stores the result in registerrd.
Compare¶
-
SLT/SLTU: (
rd=rs1<rs2? 1 : 0)Compares the values stored in registers
rs1andrs2, setsrd= 1 ifrs1<rs2(signed/unsigned), otherwiserd = 0.
Shift¶
-
Shift left/right (arithmetic): (
rd=rs1<< / >> / >>>rs2)Left/Right shifts the value stored in register
rs1by lower 5 bits ofrs2bits and stores the result in registerrd.
RV32I I-type¶
Arithmetic & Logic¶
-
Addition: (
rd=rs1+imm) -
Similarly,
andi/ori/xori/slti/sltuifor AND/OR/XOR/SLT/SLTU.
Load¶

-
Load word at
addr.to registerrd: (addr.= (number inrs1) +imm) -
Load signed/unsigned byte at
addr.to registerrd: (addr.= (number inrs1) +imm) -
Load signed/unsigned half-word at
addr.to registerrd: (addr.= (number inrs1) +imm)
RV32I S-type¶
Store¶
-
Store word at
rs2to memoryaddr.: (addr.= (number inrs1) +imm) -
Similarly,
sh: Store lower 16 bits atrs2,sb: Store lower 8 bits atrs2.
RV32I B-type¶
-
Branch on equal:
Go to statement labeled
Lif (value inrs1) == (value inrs2); otherwise, continue to next statement. -
Branch on comparison
Go to statement labeled
Lif (value inrs1) \(<\) / \(\geq\) (value inrs2); otherwise, continue to next statement.
RV32I U-type¶
RV32I J-type¶
-
Jump & Link, jump to function
- Save the address of the next instruction (PC + 4) to register
rd. - Jump to statement labeled
L.
- Save the address of the next instruction (PC + 4) to register
-
Jump & Link Register
- Save the address of the next instruction (PC + 4) to register
rd. - Jump to the address in register
rs1+imm.
- Save the address of the next instruction (PC + 4) to register
Function Call¶
Calling Convention¶
| REGISTER | NAME | USE | SAVER |
|---|---|---|---|
x0 |
zero |
The constant value 0 | N.A. |
x1 |
ra |
Return address | Caller |
x2 |
sp |
Stack pointer | Callee |
x3 |
gp |
Global pointer | -- |
x4 |
tp |
Thread pointer | -- |
x5-x7 |
t0-t2 |
Temporaries | Caller |
x8 |
s0/fp |
Saved register/Frame pointer | Callee |
x9 |
s1 |
Saved register | Callee |
x10-x11 |
a0-a1 |
Function arguments/Return values | Caller |
x12-x17 |
a2-a7 |
Function arguments | Caller |
x18-x27 |
s2-s11 |
Saved registers | Callee |
x28-x31 |
t3-t6 |
Temporaries | Caller |
Stack¶
- Stack frame may include:
- Return “instruction” address
- Parameters (spill)
- Space for other local variables
- Stack frames contiguous; stack pointer (
sp/x2) tells where bottom of stack frame is - When procedure/function begins,
spis decreased to create space; data are stored in the stack frame (push) - When procedure ends, stack frame is tossed off the stack; frees memory for future stack frames;
sprestores (pop)
Call a Function¶
-
Caller put parameters in a place where function can access them (registers), and then save caller-saved registers to stack (
ra,a0-a7,t0-t11). -
Transfer control to callee function (PC jump to function):
jal/jalr rais changed to where caller left -
Acquire (local) storage resources needed for function: change
sp(size decided when compiling);Callee push callee-saved registers to stack (e.g.,
s0-s11) -
Perform desired task of the function
-
Put result value in a place where calling code can access it (
a0,a1), and restore/pop callee-saved registers (s0-s11,sp) -
Return control to point of origin, since a function can be called from several points in a program (
jr ra); caller restores callersaved registers.