📘 参数解释
| 名称 | 含义 | 出现在哪类指令 | 来自哪里? |
|---|---|---|---|
rd |
目标寄存器 | 所有带结果的指令 | 是 x0~x31 中一个 |
rs1 |
源操作数1 | 几乎所有指令 | 是 x0~x31 中一个 |
rs2 |
源操作数2 | 大部分算术/逻辑/跳转指令 | 是 x0~x31 中一个 |
imm |
立即数(常量) | I型、S型、B型、U型、J型等 | 是写死在指令里的常量 |
📘 RISC-V 把指令按格式分成几种常见类型,每种类型有不同的编码结构:
| 类型 | 用途 | 特点 |
|---|---|---|
| R-type | 两个寄存器之间运算 | 没有立即数 |
| I-type | 一个寄存器 + 一个立即数 | 有 12 位立即数 |
| S-type | 存储指令 | 把寄存器的值存到内存 |
| B-type | 条件跳转 | 分支判断用 |
| U-type | 高位立即数 | 设置高 20 位 |
| J-type | 无条件跳转 | 跳转用 |
寄存器是 CPU 内部用来 临时存数据 的地方,你可以把它当作一个 小容量、超级快的内存单元。
RISC-V 有 32 个这样的寄存器:x0 到 x31,每个寄存器都有个别名,比如:
x1通常叫ra(return address)x2是sp(stack pointer)x10~x17用作参数寄存器(a0~a7)
立即数是指令中直接写的常量,比如 5, -1,这些不是从寄存器里来的,而是“写死”的数。
imm是一个 12 位的带符号数(范围 -2048 到 2047)- “sign-extended” 意思是扩展成 32 位的时候要保留正负号
- 不会报溢出错(就算溢出了也只保留结果的低 32 位)
ADDI rd, rs1, 0就是把 rs1 的值原封不动地复制给 rd,相当于MV rd, rs1
比如:
SLTI x5, x6, 0 ; 如果 x6 是负数,x5=1;否则 x5=0SLTIU x5, x6, 1这是一个非常巧妙的用法,用来判断 x6 是否等于 0!
因为:
- 如果 x6 == 0,确实 0 < 1(无符号)
- 如果 x6 != 0,那就是大于或等于 1,结果是 false
所以它相当于:
SEQZ x5, x6 ; “Set if EQual to Zero”这三个指令就是把寄存器的值和一个立即数按位操作:
| 指令 | 作用 |
|---|---|
ANDI rd, rs1, imm |
rd = rs1 & imm (按位与) |
ORI rd, rs1, imm |
rd = rs1 | imm (按位或) |
XORI rd, rs1, imm |
rd = rs1 ^ imm (按位异或) |
XORI x5, x6, -1-1在二进制是全1XOR一个数和0b111...111的结果就是每一位取反- 所以它实现了:
NOT x5, x6+---------------------+
| NAVY Apps | ← 学生写用户程序 (用户态)
+---------------------+
↓ syscall
+---------------------+
| Nanos-lite OS | ← 学生实验操作系统(内核态)
+---------------------+
↓ AM调用
+---------------------+
| AM 抽象机 | ← 学生不修改,用于屏蔽硬件差异
+---------------------+
↓ 运行平台
+---------------------+
| NEMU 模拟器 | ← RISC-V 教学模拟器,完全开源
+---------------------+
AM = TRM + IOE + CTE + VME + MPE
- TRM(Turing Machine) - 图灵机, 最简单的运行时环境, 为程序提供基本的计算能力
- IOE(I/O Extension) - 输入输出扩展, 为程序提供输出输入的能力
- CTE(Context Extension) - 上下文扩展, 为程序提供上下文管理的能力
- VME(Virtual Memory Extension) - 虚存扩展, 为程序提供虚存管理的能力
- MPE(Multi-Processor Extension) - 多处理器扩展, 为程序提供多处理器通信的能力