本文介绍完整的Risc-V指令集
文章内容基于该网站教学。
整套RV32I基础指令集仅需大约40多条指令,也是处理器必须识别的全部 “指令词汇”。这些指令可划归为下面这几大类:

依次为算术与逻辑运算指令、立即数运算指令、加载/存储指令、分支指令、跳转指令、高位立即数指令、系统类指令。
算术与逻辑运算(寄存器 - 寄存器型)——R-type指令(10条)
选取两个寄存器中的数据执行运算操作,并存储运算结果。这类指令是处理器最常用的基础指令:
| 指令 |
含义 |
| add / sub |
rd = rs1 + rs2 / rd = rs1 − rs2 |
| and / or / xor |
按位与 / 按位或 / 按位异或 |
| sll / srl / sra |
逻辑左移 / 逻辑右移 / 算术右移(保留符号位) |
| slt / sltu |
(对应有符号/无符号)rd = (rs1 < rs2) ? 1 : 0 |
1
2
3
4
5
6
7
8
9
10
11
|
# 用法
add rd, rs1, rs2 表示 rd = rs1 + rs2
sub rd, rs1, rs2 表示 rd = rs1 - rs2
and rd, rs1, rs2 表示 rd = rs1 & rs2
or rd, rs1, rs2 表示 rd = rs1 | rs2
xor rd, rs1, rs2 表示 rd = rs1 ^ rs2
sll rd, rs1, rs2 表示 rd = rs1 << rs2
srl rd, rs1, rs2 表示 rd = rs1 >> rs2
sra rd, rs1, rs2 表示 rd = rs1 >>> rs2
slt rd, rs1, rs2 表示 rd = (rs1 < rs2) ? 1 : 0
sltu rd, rs1, rs2 表示 rd = (rs1 < rs2) ? 1 : 0
|
算术与逻辑运算(寄存器 - 立即数型)(9条)
| 指令 |
含义 |
| addi |
rd = rs1 + 立即数 (不存在 “立即数减法 subi” 指令,只需传入负数即可实现减法) |
| andi / ori / xori |
与常量按位与 / 按位或 / 按位异或 |
| slli / srli / srai |
逻辑左移 / 逻辑右移 / 算术右移常量位 |
| slti / sltiu |
(对应有符号/无符号)rd = (rs1 < 立即数) ? 1 : 0 |
1
2
3
4
5
6
7
8
9
10
|
#用法
addi rd, rs1, imm 表示 rd = rs1 + imm
andi rd, rs1, imm 表示 rd = rs1 & imm
ori rd, rs1, imm 表示 rd = rs1 | imm
xori rd, rs1, imm 表示 rd = rs1 ^ imm
slli rd, rs1, imm 表示 rd = rs1 << imm
srli rd, rs1, imm 表示 rd = rs1 >> imm
srai rd, rs1, imm 表示 rd = rs1 >>> imm
slti rd, rs1, imm 表示 rd = (rs1 < imm) ? 1 : 0
sltiu rd, rs1, imm 表示 rd = (rs1 < imm) ? 1 : 0
|
与存储器交互(8条)
| 指令 |
含义 |
| lw |
将内存中的一个32位字加载至目标寄存器rd |
| lh / lb |
加载半字(16位)/字节(8位)到rd(带符号位扩展) |
| lhu / lbu |
加载半字/字节数据到rd,(无符号位零扩展) |
| sw / sh / sb |
将寄存器rs2中的字数据/半字数据/字节数据存入存储器 |
1
2
3
4
5
6
7
8
9
|
# 用法
lw rd, imm(rs1) 表示 rd = MEM[rs1 + imm]
lh rd, imm(rs1) 表示 rd = MEM[rs1 + imm](高位扩展符号位)
lb rd, imm(rs1) 表示 rd = MEM[rs1 + imm](高位扩展符号位)
lhu rd, imm(rs1) 表示 rd = MEM[rs1 + imm](高位扩展0)
lbu rd, imm(rs1) 表示 rd = MEM[rs1 + imm](高位扩展0)
sw rs2, imm(rs1) 表示 MEM[rs1 + imm] = rs2
sh rs2, imm(rs1) 表示 MEM[rs1 + imm] = rs2的低 16 位
sb rs2, imm(rs1) 表示 MEM[rs1 + imm] = rs2的低 8 位
|
分支指令(6条)
CPU执行“if(条件判断)”语句:分支指令会对比两个寄存器的值,仅当判定条件成立时才执行跳转操作,若条件不成立,程序则直接顺序向下执行。
| 指令 |
表达式(成立则跳转) |
| beq / bne |
rs1 == rs2 / rs1 != rs2 |
| blt / bge |
rs1 < rs2 / rs1 ≥ rs2 (有符号数) |
| bltu / bgeu |
rs1 < rs2 / rs1 ≥ rs2 (无符号数) |
1
2
3
4
5
6
7
|
# 用法
beq rs1, rs2, imm 表示 if (rs1 == rs2) 跳转到 PC + 偏移地址
bne rs1, rs2, imm 表示 if (rs1 != rs2) 跳转到 PC + 偏移地址
blt rs1, rs2, imm 表示 if (rs1 < rs2) 跳转到 PC + 偏移地址
bge rs1, rs2, imm 表示 if (rs1 >= rs2) 跳转到 PC + 偏移地址
bltu rs1, rs2, imm 表示 if (rs1 < rs2) 跳转到 PC + 偏移地址
bgeu rs1, rs2, imm 表示 if (rs1 >= rs2) 跳转到 PC + 偏移地址
|
高位立即数指令(2条)
| 指令 |
含义 |
| lui |
把指令内的20位立即数放置到寄存器高20位,寄存器低12位清零。 |
| auipc |
20位立即数左移12位后与当前PC值相加,结果存入目标寄存器;常用于生成PC相对地址,实现位置无关寻址 |
1
2
3
|
# 用法
lui rd, imm 表示 rd = imm << 12
auipc rd, imm 表示 rd = (imm << 12) + PC
|
跳转指令(2条)
| 指令 |
含义 |
| jal |
Jump and link,PC 相对跳转。跳转目标 = PC + 符号扩展后的立即数,自动把当前 PC+4(下一条指令地址)写入 rd 寄存器,主要用于函数调用 |
| jalr |
寄存器间接跳转。跳转地址由「rs1 寄存器值 + 12 位符号扩展立即数」给出,同样会将 PC+4 存入 rd;最常用格式 jalr x0,0(x1) 实现函数返回,也可用于动态计算地址跳转 |
1
2
3
|
# 用法
jal rd, imm 表示 PC = PC + imm,rd = PC_old + 4
jalr rd, imm(rs1) 表示 PC = rs1 + imm,rd = PC_old + 4
|
伪指令
伪指令没有对应的独立机器码,汇编器在编译阶段,会自动把一条伪指令翻译成一条或多条真实硬件指令执行。只是为了编写汇编代码更简洁、好理解。
| 伪指令 |
翻译后指令 |
补充说明 |
| li rd, 5 |
addi rd, x0, 5 |
12位范围内小立即数赋值;32位大数会编译为 lui + addi 组合 |
| mv rd, rs |
addi rd, rs, 0 |
复制寄存器 |
| nop |
addi x0, x0, 0 |
不做任何操作 |
| j label |
jal x0, label |
跳转不保存返回地址 |
| ret |
jalr x0, 0(x1) |
在跳转操作后,返回x1寄存器内的返回地址 |
特殊指令(10条)
CSR(控制状态寄存器)属于独立硬件寄存器组,和通用寄存器 x0~x31 物理分离,仅能使用以上 CSR 专用指令访问,普通运算指令无法读写。
| 指令 |
含义 |
| ecall |
环境调用,触发系统调用异常,向内核申请服务 |
| ebreak |
断点指令,触发调试异常,用于 GDB 程序调试暂停 |
| fence |
数据内存屏障,管控 Load/Store 访存乱序 |
| fence.i |
指令流水线屏障,清空指令缓存、刷新指令流 |
| csrrw |
CSR 读写:读出旧值到 rd,写入 rs 数据至 CSR |
| csrrs |
CSR 读置位:读出旧值到 rd,使用 rs 按位或置 1 寄存器 bit |
| csrrc |
CSR 读清零:读出旧值到 rd,使用 rs 按位与清零寄存器 bit |
| csrrwi |
csrrw 立即数版本,使用 5 位立即数写入 CSR |
| csrrsi |
csrrs 立即数版本,使用立即数做按位置位 |
| csrrci |
csrrc 立即数版本,使用立即数做按位清零 |
1
2
3
4
5
6
7
8
9
10
11
|
# 用法
ecall # 发起系统调用
ebreak # 触发调试断点异常
fence # 数据内存屏障
fence.i # 指令流水线刷新屏障
csrrw rd, csr, rs1 表示 rd = csr,csr = rs1
csrrs rd, csr, rs1 表示 rd = csr,csr = csr | rs1
csrrc rd, csr, rs1 表示 rd = csr,csr = csr & ~rs1
csrrwi rd, csr, imm 表示 rd = csr,csr = imm
csrrsi rd, csr, imm 表示 rd = csr,csr = csr | imm
csrrci rd, csr, imm 表示 rd = csr,csr = csr & ~imm
|
参考指令字段格式:

opcode对照表
