🧱 RV32I 整数指令集

本章基于 RISC-V 指令集手册(Volume I: Unprivileged Spec, Version 2.1) 编写。 若存在与标准差异,请以 2.1 版本为准。

XLEN的约定

架构名称 描述
riscv32 XLEN = 32 的 RISC-V 架构(即 RV32I 或 RV32E),使用 32 位寄存器和地址空间。
riscv64 XLEN = 64 的 RISC-V 架构(即 RV64I 或 RV64E),使用 64 位寄存器和地址空间。

🧩 一、RV32I 简介

RV32I 是整个 RISC-V 架构的核心,所有其他扩展(如 M、A、F、D、C)都是在此基础上叠加的。


🧩 二、RISC-V 寄存器与 ABI 命名

1️⃣ 寄存器基础概念

RISC-V 架构包含 32 个通用寄存器(x0–x31),每个寄存器宽度为 32 位(RV32)或 64 位(RV64)。 这些寄存器可用于整数计算、地址、参数传递等。

寄存器编号 名称 说明
x0–x31 通用寄存器 每个都是 32 位,可用于整数计算、地址、参数传递等

💡 注意:x0 永远等于 0。写入它的值将被丢弃。


2️⃣ ABI(Application Binary Interface)命名

虽然硬件内部寄存器编号为 x0–x31, 但编译器与汇编通常使用更具语义的 ABI 命名。 这些别名在函数调用、参数传递与系统调用中非常关键。

编号 ABI 名 含义
x0 zero 恒为 0
x1 ra 返回地址 (Return Address)
x2 sp 栈指针 (Stack Pointer)
x3 gp 全局指针 (Global Pointer)
x4 tp 线程指针 (Thread Pointer)
x5–x7 t0–t2 临时寄存器 (Temporaries)
x8 s0 / fp 保存寄存器 / 帧指针
x9 s1 保存寄存器
x10–x11 a0–a1 参数 / 返回值
x12–x17 a2–a7 参数寄存器
x18–x27 s2–s11 保存寄存器(callee-saved)
x28–x31 t3–t6 临时寄存器(caller-saved)

3️⃣ 示例:两种写法

写法 含义
addi x5, x1, 10 用编号表示(硬件角度):x5 = x1 + 10
addi t0, ra, 10 用 ABI 名(软件角度):t0 = ra + 10

在汇编和调试器输出中,你通常看到的是 ABI 命名,因为它更直观。


4️⃣ 调用约定分类

分类 寄存器 保存责任
临时寄存器 t0–t6 调用者保存
参数/返回值 a0–a7 调用者设置
保存寄存器 s0–s11 被调用者保存
特殊寄存器 sp, ra, gp, tp 系统/编译器管理

🧠 三、指令编码格式(Instruction Format)

RISC-V 的所有指令长度均为 32 位,但根据操作类型不同,编码格式也不同。 常见的 6 种基础格式如下:

格式 典型用途 举例(ABI 命名)
R-type 寄存器对寄存器运算 add a0, a1, a2
I-type 立即数运算 / 加载 / 跳转 addi t0, sp, 16lw a0, 0(sp)
S-type 存储指令 sw a1, 8(sp)
B-type 条件分支 beq a0, a1, loop
U-type 高位立即数加载 lui t0, 0x12345
J-type 无条件跳转 jal ra, main

🧩 四、指令格式详解

以下为每种格式的结构及说明(bit 编号从右至左 0–31)。


I-type(立即数型)

用于立即数操作、加载指令、跳转指令等。

text
┌──────────────┬──────┬───────┬──────┬────────┐
│ imm[11:0]    │ rs1  │ funct3│  rd  │ opcode │
├──────────────┼──────┼───────┼──────┼────────┤
│ 31..20       │19..15│14..12 │11..7 │ 6..0   │
└──────────────┴──────┴───────┴──────┴────────┘

📘 示例:addi t0, ra, 10


S-type(存储型)

text
┌──────────────┬──────┬──────┬───────┬──────────┬────────┐
│ imm[11:5]    │ rs2  │ rs1  │ funct3│ imm[4:0] │ opcode │
├──────────────┼──────┼──────┼───────┼──────────┼────────┤
│ 31..25       │24..20│19..15│14..12 │11..7     │ 6..0   │
└──────────────┴──────┴──────┴───────┴──────────┴────────┘

📘 示例:sw a0, 8(sp)


B-type(分支型)

text
┌──────┬──────────┬──────┬──────┬───────┬────────┬──────┬────────┐
│imm[12]│imm[10:5]│ rs2  │ rs1  │ funct3│imm[4:1]│imm[11]│ opcode │
├──────┼──────────┼──────┼──────┼───────┼────────┼──────┼────────┤
│ 31   │30..25    │24..20│19..15│14..12 │11..8   │7     │6..0    │
└──────┴──────────┴──────┴──────┴───────┴────────┴──────┴────────┘

📘 示例:beq a0, a1, loop


U-type(高位立即数型)

text
┌────────────────────────┬──────┬────────┐
│ imm[31:12]             │  rd  │ opcode │
├────────────────────────┼──────┼────────┤
│ 31..12                 │11..7 │ 6..0   │
└────────────────────────┴──────┴────────┘

📘 示例:lui t0, 0x12345


J-type(跳转型)

text
┌──────┬──────────┬──────┬──────────┬──────┬────────┐
│imm[20]│imm[10:1]│imm[11]│imm[19:12]│  rd  │ opcode │
├──────┼──────────┼──────┼──────────┼──────┼────────┤
│31    │30..21    │20    │19..12    │11..7 │ 6..0   │
└──────┴──────────┴──────┴──────────┴──────┴────────┘

📘 示例:jal ra, func


🧩 五、格式对比表

类型 用途 典型例子
R 寄存器运算 add a0, a1, a2
I 立即数/加载 addi a0, a0, 4
S 存储 sw a0, 0(sp)
B 条件跳转 bne a0, zero, loop
U 高位立即数 lui t0, 0x12345
J 无条件跳转 jal ra, label

📘 六、小结

格式 常用指令 用途
R add, sub, and, or, sll 寄存器间运算
I addi, lw, jalr 立即数或加载
S sw, sh, sb 存储
B beq, bne 条件跳转
U lui, auipc 高位立即数
J jal 无条件跳转