RISC V
RISC-V (pronounced “risk-five”) is an open-standard Instruction Set Architecture (ISA) based on the principles of Reduced Instruction Set Computing (RISC). It was designed to be simple, modular, and extensible—ideal for research, education, and commercial use.
Core Components
Base ISA
RV32I, RV64I, and RV128I — 32-bit, 64-bit, and 128-bit versions.
Includes only essential instructions (load, store, arithmetic, control flow).
Standard Extensions
M: Integer Multiplication and DivisionA: Atomic InstructionsF: Single-Precision Floating-PointD: Double-Precision Floating-PointC: Compressed InstructionsV: Vector ExtensionH: Hypervisor Extension
Privilege Modes
- User Mode (
U) - Supervisor Mode (
S) - Machine Mode (
M)
Assembly
RISC-V assembly is a low-level programming language that directly maps to the RISC-V Instruction Set Architecture (ISA). It uses a load-store architecture, meaning that all computations are done using registers, and memory is accessed only with explicit load and store instructions.
📦 Registers
RISC-V defines 32 general-purpose registers: x0 to x31. These can also be referred to using ABI (Application Binary Interface) names:
| Register | ABI Name | Purpose |
|---|---|---|
x0 | zero | Constant 0 |
x1 | ra | Return address |
x2 | sp | Stack pointer |
x3 | gp | Global pointer |
x4 | tp | Thread pointer |
x5-x7 | t0-t2 | Temporary |
x8 | s0/fp | Saved / frame ptr |
x9 | s1 | Saved register |
x10-x17 | a0-a7 | Function arguments |
x18-x27 | s2-s11 | Saved registers |
x28-x31 | t3-t6 | Temporaries |
🧪 RISC-V Toolchain
You can write and test RISC-V assembly using:
- Assembler:
riscv64-unknown-elf-as - Linker:
riscv64-unknown-elf-ld - Simulator:
spike,qemu-riscv64 - Compiler (C to RISC-V):
riscv64-unknown-elf-gcc
📜 RISC-V Instruction Cheat Sheet
🧮 Arithmetic
| Instruction | Description |
|---|---|
add | Add |
sub | Subtract |
mul | Multiply (M extension) |
div | Divide (M extension) |
rem | Remainder (modulo) |
addi | Add immediate |
andi | Bitwise AND immediate |
ori | Bitwise OR immediate |
xori | Bitwise XOR immediate |
🧠 Logical / Bit Manipulation
| Instruction | Description |
|---|---|
and | Bitwise AND |
or | Bitwise OR |
xor | Bitwise XOR |
sll | Shift Left Logical |
srl | Shift Right Logical |
sra | Shift Right Arithmetic |
📦 Memory Access
| Instruction | Description |
|---|---|
lw | Load word (32-bit) |
lh | Load halfword (16-bit) |
lb | Load byte (8-bit) |
lbu | Load byte unsigned |
sw | Store word (32-bit) |
sh | Store halfword |
sb | Store byte |
la | Load address (pseudoinstruction) |
🔁 Branch / Control Flow
| Instruction | Description |
|---|---|
beq | Branch if equal |
bne | Branch if not equal |
blt | Branch if less than (signed) |
bge | Branch if greater or equal (signed) |
jal | Jump and link |
jalr | Jump and link register |
🏗️ System / Function
| Instruction | Description |
|---|---|
ecall | System call |
ret | Return from function (jalr) |
nop | No operation (addi x0, x0, 0) |
li | Load immediate (pseudo) |
mv | Move register (pseudo) |
Hello World in RISC-V Assembly (Linux)
This program uses the Linux syscalls:
write(syscall64) to write to stdoutexit(syscall93) to terminate
# hello.S
.section .data
message:
.ascii "Hello, world!\n"
len = . - message
.section .text
.globl _start
_start:
li a7, 64 # syscall: write
li a0, 1 # fd: stdout
la a1, message # buffer address
li a2, len # buffer length
ecall # invoke syscall
li a7, 93 # syscall: exit
li a0, 0 # exit code 0
ecall