HomeRISC-V from ScratchDay 2
DAY 2 · THE RISC-V ISA

Registers & the RV32I Base

By EcrioniX · Updated Jun 6, 2026

Before a CPU can add, compare or jump, it needs somewhere to keep the numbers it's working on right now. Those little holding slots are registers — the most-used storage in the whole machine. Today we'll meet RISC-V's 32 registers, the magical "always-zero" one, and the friendly names engineers give them — all in plain English.

1. What is a register? (the simplest version)

A register is a tiny, super-fast storage slot inside the CPU that holds one number. That's it. When the processor adds two numbers, both numbers sit in registers, and the answer goes into a register too.

💡 Your desk vs. the warehouse

Registers are like the items on your desk — right in front of you, grabbable instantly. Memory (RAM) is the warehouse down the hall — huge, but slow to fetch from. You keep what you're actively using on the desk (registers) and only walk to the warehouse (memory) when you must. A CPU works the same way: do the math in registers, touch memory only when needed.

2. Why not just use memory?

Speed. Reading a register takes effectively no time (it's right inside the core), while reaching out to main memory is dramatically slower. So RISC-V is a "load-store" architecture: arithmetic instructions work only on registers, and there are special instructions just for moving data between registers and memory (we'll meet lw/sw on Day 13). Keep that in mind — it shapes the whole instruction set.

3. The 32 registers: x0–x31

RV32I gives you exactly 32 general-purpose registers, named x0, x1, x2, … x31. Each one is 32 bits wide (remember the "32" in RV32I — that's the size of each register). Picture them as a numbered row of 32 boxes, each holding a 32-bit number:

The RV32I register file — 32 boxes, 32 bits each x0 = 0 x1 x2 x3 · · · x30 x31 hardwired 0 |<—————————— each box is 32 bits wide ——————————>| bit 31bit 0 0 1 0 1 1 0 0 1 …
Figure — 32 registers (x0–x31), each holding one 32-bit value. x0 is permanently 0.

Collectively this set of registers is called the register file — and building it in Verilog is exactly what we'll do on Day 9.

4. x0 — the register that's always zero

One register is special. x0 is hardwired to the value 0. Read it → you always get 0. Write to it → the write is silently thrown away. It sounds useless, but it's a brilliant trick that makes the instruction set smaller:

This is why RISC-V needs fewer real instructions — many handy operations are just clever uses of x0.

5. Friendly names: the ABI & register roles

Numbers like x18 tell you nothing about a register's job. So RISC-V defines ABI names — human-friendly aliases — as part of the calling convention (the agreed rules that let separately-written code work together, like the AAPCS in ARM). They're the same physical registers, just named by role:

RegisterABI nameRole
x0zeroconstant 0 (hardwired)
x1rareturn address (where a function returns to)
x2spstack pointer
x3gpglobal pointer
x4tpthread pointer
x5–x7t0–t2temporaries (scratch, caller-saved)
x8s0 / fpsaved register / frame pointer
x9s1saved register (callee-saved)
x10–x11a0–a1function arguments & return values
x12–x17a2–a7more function arguments
x18–x27s2–s11saved registers (callee-saved)
x28–x31t3–t6more temporaries (caller-saved)

Don't memorize this — just know the common ones: a0–a7 pass arguments (and a0 returns the result), ra remembers where a function should return, sp points at the stack, and t/s registers are scratch vs. preserved. We'll use them naturally as we go (full calling convention on Day 5).

6. The Program Counter (PC)

There's one more vital register that's not one of the 32: the Program Counter (PC). It holds the address of the instruction currently being run — basically a bookmark in your program. After each instruction the PC normally advances by 4 (instructions are 4 bytes = 32 bits each) to point at the next one; a branch or jump changes the PC to somewhere else, which is how loops and if-statements work. Building the PC is Day 8.

7. Registers in action

Here's a tiny RISC-V program that shows registers, x0, and ABI names working together. Copy or download it — by Day 15 our CPU will actually run code like this:

regs_demo.s — RISC-V assembly
# Show how registers are used. Result ends up in a0.
        li   t0, 7          # t0 (x5)  = 7        ("load immediate")
        li   t1, 5          # t1 (x6)  = 5
        add  t2, t0, t1     # t2 (x7)  = 7 + 5 = 12
        add  a0, t2, zero   # a0 (x10) = t2 + x0  -> copy result into a0 (=12)
        # x0/zero tricks:
        add  t3, zero, zero # t3 = 0 + 0 = 0      (clear a register)
        # 'li' and 'mv' are pseudo-instructions the assembler turns into
        # real RV32I ops (e.g. addi t0, x0, 7).

Notice add a0, t2, zero — that's the x0 copy trick from §4. And li/mv are pseudo-instructions: convenient shorthands the assembler expands into real RV32I instructions (e.g. li t0, 7 becomes addi t0, x0, 7). We'll unpack instruction encodings on Day 3.

✅ Day 2 in one line

RV32I has 32 fast 32-bit registers (x0–x31) where the CPU does its work; x0 is always 0 (a handy free constant); registers also have ABI names (a0–a7, ra, sp, t/s…) describing their job; and a separate Program Counter tracks which instruction is running. Arithmetic happens in registers — memory is touched only via load/store.

🎯 Day 2 takeaways

Quick check

  1. How many general-purpose registers does RV32I have, and how wide is each?
  2. What happens when you read x0? When you write to it?
  3. Which registers carry function arguments, and which holds the return address?
  4. What does the Program Counter store?

FAQ

What is a register?

A tiny, very fast storage slot inside the CPU holding one value the processor is actively working on.

How many registers in RV32I?

32 general-purpose registers (x0–x31), each 32 bits wide, plus a separate program counter.

Why is x0 always zero?

It's hardwired to 0 — reads give 0, writes are ignored — which provides a free constant and simplifies the instruction set.

What are ABI names?

Role-based aliases (a0–a7, ra, sp, t0–t6, s0–s11) for the numbered registers, defined by the calling convention.

Previous
← Day 1: The plan

← Back to the full roadmap  ·  Open the Verilog simulator →