(基于 Waterman and Asanovi'c 2017 的表 19.2)
| 指令位分布(31 25 24 20 19 15 14 12 11 7 6 0) | 立即数/寄存器字段 | 操作码 | 格式类型 | 指令名称 |
|---|---|---|---|---|
| imm[31:12] | - | - | - | rd | 0110111 | imm[31:12]、rd | 0110111 | U | lui |
| imm[31:12] | - | - | - | rd | 0010111 | imm[31:12]、rd | 0010111 | U | auipc |
| imm[20|10:1|11|19:12] | - | - | - | rd | 1101111 | imm[20|10:1|11|19:12]、rd | 1101111 | J | jal |
| imm[11:0] | rs1 | 000 | rd | 1100111 | imm[11:0]、rs1、rd | 1100111 | I | jalr |
| imm[12|10:5] | rs2 | rs1 | 000 | imm[4:1|11] | 1100011 | imm[12|10:5]、rs2、rs1、imm[4:1|11] | 1100011 | B | beq |
| imm[12|10:5] | rs2 | rs1 | 001 | imm[4:1|11] | 1100011 | imm[12|10:5]、rs2、rs1、imm[4:1|11] | 1100011 | B | bne |
| imm[12|10:5] | rs2 | rs1 | 100 | imm[4:1|11] | 1100011 | imm[12|10:5]、rs2、rs1、imm[4:1|11] | 1100011 | B | blt |
| imm[12|10:5] | rs2 | rs1 | 101 | imm[4:1|11] | 1100011 | imm[12|10:5]、rs2、rs1、imm[4:1|11] | 1100011 | B | bge |
| imm[12|10:5] | rs2 | rs1 | 110 | imm[4:1|11] | 1100011 | imm[12|10:5]、rs2、rs1、imm[4:1|11] | 1100011 | B | bltu |
| imm[12|10:5] | rs2 | rs1 | 111 | imm[4:1|11] | 1100011 | imm[12|10:5]、rs2、rs1、imm[4:1|11] | 1100011 | B | bgeu |
| imm[11:0] | rs1 | 000 | rd | 0000011 | imm[11:0]、rs1、rd | 0000011 | I | lb |
| imm[11:0] | rs1 | 001 | rd | 0000011 | imm[11:0]、rs1、rd | 0000011 | I | lh |
| imm[11:0] | rs1 | 010 | rd | 0000011 | imm[11:0]、rs1、rd | 0000011 | I | lw |
| imm[11:0] | rs1 | 100 | rd | 0000011 | imm[11:0]、rs1、rd | 0000011 | I | lbu |
| imm[11:0] | rs1 | 101 | rd | 0000011 | imm[11:0]、rs1、rd | 0000011 | I | lhu |
| imm[11:5] | rs2 | rs1 | 000 | imm[4:0] | 0100011 | imm[11:5]、rs2、rs1、imm[4:0] | 0100011 | S | sb |
| imm[11:5] | rs2 | rs1 | 001 | imm[4:0] | 0100011 | imm[11:5]、rs2、rs1、imm[4:0] | 0100011 | S | sh |
| imm[11:5] | rs2 | rs1 | 010 | imm[4:0] | 0100011 | imm[11:5]、rs2、rs1、imm[4:0] | 0100011 | S | sw |
| imm[11:0] | rs1 | 000 | rd | 0010011 | imm[11:0]、rs1、rd | 0010011 | I | addi |
| imm[11:0] | rs1 | 010 | rd | 0010011 | imm[11:0]、rs1、rd | 0010011 | I | slti |
| imm[11:0] | rs1 | 011 | rd | 0010011 | imm[11:0]、rs1、rd | 0010011 | I | sltiu |
| imm[11:0] | rs1 | 100 | rd | 0010011 | imm[11:0]、rs1、rd | 0010011 | I | xori |
| imm[11:0] | rs1 | 110 | rd | 0010011 | imm[11:0]、rs1、rd | 0010011 | I | ori |
| imm[11:0] | rs1 | 111 | rd | 0010011 | imm[11:0]、rs1、rd | 0010011 | I | andi |
| 0000000 | shamt | rs1 | 001 | rd | 0010011 | shamt、rs1、rd | 0010011 | I | slli |
| 0000000 | shamt | rs1 | 101 | rd | 0010011 | shamt、rs1、rd | 0010011 | I | srli |
| 0100000 | shamt | rs1 | 101 | rd | 0010011 | shamt、rs1、rd | 0010011 | I | srai |
| 0000000 | rs2 | rs1 | 000 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | add |
| 0100000 | rs2 | rs1 | 000 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | sub |
| 0000000 | rs2 | rs1 | 001 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | sll |
| 0000000 | rs2 | rs1 | 010 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | slt |
| 0000000 | rs2 | rs1 | 011 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | sltu |
| 0000000 | rs2 | rs1 | 100 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | xor |
| 0000000 | rs2 | rs1 | 101 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | srl |
| 0100000 | rs2 | rs1 | 101 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | sra |
| 0000000 | rs2 | rs1 | 110 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | or |
| 0000000 | rs2 | rs1 | 111 | rd | 0110011 | rs2、rs1、rd | 0110011 | R | and |
| 0000 | pred | succ | 00000 | 000 | 00000 | 0001111 | pred、succ | 0001111 | I | fence |
| 0000 0000 0000 | 00000 | 001 | 00000 | 0001111 | - | 0001111 | I | fence.i |
| 000000000000 | 00000 | 000 | 00000 | 1110011 | - | 1110011 | I | ecall |
| 000000000000 | 00000 | 000 | 00000 | 1110011 | - | 1110011 | I | ebreak |
| csr | rs1 | 001 | rd | 1110011 | csr、rs1、rd | 1110011 | I | csrrw |
| csr | rs1 | 010 | rd | 1110011 | csr、rs1、rd | 1110011 | I | csrrs |
| csr | rs1 | 011 | rd | 1110011 | csr、rs1、rd | 1110011 | I | csrrc |
| csr | zimm | 101 | rd | 1110011 | csr、zimm、rd | 1110011 | I | csrrwi |
| csr | zimm | 110 | rd | 1110011 | csr、zimm、rd | 1110011 | I | csrrsi |
| csr | zimm | 111 | rd | 1110011 | csr、zimm、rd | 1110011 | I | csrrci |
以下是完善后的RV32I操作码映射表,补充了每条指令的详细说明,并优化了格式的清晰度,便于书稿排版使用:
我将详细讲解RV32I指令集中的每条指令,按照指令格式分类进行说明。
RV32I指令集包含6种基本格式:
指令格式:imm[31:12] | rd | 0110111
操作:rd = imm << 12
功能:将20位立即数左移12位(加载到高位),低12位补零
用途:构建32位常数的高20位
示例:lui x5, 0x12345 # x5 = 0x12345000
指令格式:imm[31:12] | rd | 0010111
操作:rd = PC + (imm << 12)
功能:将20位立即数左移12位后与当前PC相加
用途:位置无关代码,构建全局地址
示例:auipc x6, 0x1000 # x6 = PC + 0x1000000
指令格式:imm[20|10:1|11|19:12] | rd | 1101111
操作:rd = PC + 4; PC = PC + sign_extend(imm)
功能:跳转到目标地址,同时保存返回地址到rd
立即数编码:imm[20:1](跳转偏移,字节对齐)
用途:函数调用、长距离跳转
示例:jal x1, function # 调用函数,返回地址保存在x1
指令格式:imm[11:0] | rs1 | 000 | rd | 1100111
操作:rd = PC + 4; PC = (rs1 + sign_extend(imm)) & ~1
功能:通过寄存器间接跳转,最低位清零
用途:函数返回、虚函数调用
示例:jalr x0, 0(x1) # 跳转到x1地址,不保存返回地址
LB: imm[11:0] | rs1 | 000 | rd | 0000011 # 加载字节(有符号扩展)
LH: imm[11:0] | rs1 | 001 | rd | 0000011 # 加载半字(有符号扩展)
LW: imm[11:0] | rs1 | 010 | rd | 0000011 # 加载字
LBU: imm[11:0] | rs1 | 100 | rd | 0000011 # 加载字节(无符号扩展)
LHU: imm[11:0] | rs1 | 101 | rd | 0000011 # 加载半字(无符号扩展)
操作:rd = memory[rs1 + sign_extend(imm)]
ADDI: rd = rs1 + sign_extend(imm) # 立即数加法
SLTI: rd = (rs1 < sign_extend(imm)) ? 1 : 0 # 有符号比较置位
SLTIU: rd = (rs1 < sign_extend(imm)) ? 1 : 0 # 无符号比较置位
XORI: rd = rs1 ^ sign_extend(imm) # 立即数异或
ORI: rd = rs1 | sign_extend(imm) # 立即数或
ANDI: rd = rs1 & sign_extend(imm) # 立即数与
SLLI: 0000000 | shamt | rs1 | 001 | rd | 0010011 # 逻辑左移
SRLI: 0000000 | shamt | rs1 | 101 | rd | 0010011 # 逻辑右移
SRAI: 0100000 | shamt | rs1 | 101 | rd | 0010011 # 算术右移
操作:
SLLI: rd = rs1 << shamt
SRLI: rd = rs1 >> shamt (逻辑右移,补0)
SRAI: rd = rs1 >> shamt (算术右移,补符号位)
注意:shamt只有低5位有效(0-31)
指令格式:imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1|11] | 1100011
立即数编码:imm[12:1](分支偏移,字节对齐)
BEQ: if (rs1 == rs2) PC += sign_extend(imm) # 相等跳转
BNE: if (rs1 != rs2) PC += sign_extend(imm) # 不等跳转
BLT: if (rs1 < rs2) PC += sign_extend(imm) # 有符号小于跳转
BGE: if (rs1 >= rs2) PC += sign_extend(imm) # 有符号大于等于跳转
BLTU: if (rs1 < rs2) PC += sign_extend(imm) # 无符号小于跳转
BGEU: if (rs1 >= rs2) PC += sign_extend(imm) # 无符号大于等于跳转
指令格式:imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | 0100011
操作:memory[rs1 + sign_extend(imm)] = rs2[7:0]或[15:0]或[31:0]
SB: 存储字节(rs2的低8位)
SH: 存储半字(rs2的低16位)
SW: 存储字(rs2的32位)
ADD: 0000000 | rs2 | rs1 | 000 | rd | 0110011 # 加法
SUB: 0100000 | rs2 | rs1 | 000 | rd | 0110011 # 减法
SLL: 0000000 | rs2 | rs1 | 001 | rd | 0110011 # 逻辑左移
SLT: 0000000 | rs2 | rs1 | 010 | rd | 0110011 # 有符号比较置位
SLTU: 0000000 | rs2 | rs1 | 011 | rd | 0110011 # 无符号比较置位
XOR: 0000000 | rs2 | rs1 | 100 | rd | 0110011 # 异或
SRL: 0000000 | rs2 | rs1 | 101 | rd | 0110011 # 逻辑右移
SRA: 0100000 | rs2 | rs1 | 101 | rd | 0110011 # 算术右移
OR: 0000000 | rs2 | rs1 | 110 | rd | 0110011 # 或
AND: 0000000 | rs2 | rs1 | 111 | rd | 0110011 # 与
指令格式:0000 | pred | succ | 00000 | 000 | 00000 | 0001111
功能:内存屏障,保证内存访问顺序
pred: 前驱操作(4位)
succ: 后继操作(4位)
指令格式:0000 0000 0000 | 00000 | 001 | 00000 | 0001111
功能:指令流同步,用于自修改代码
指令格式:000000000000 | 00000 | 000 | 00000 | 1110011
功能:环境调用,向执行环境发出请求
用途:系统调用、调试器交互
指令格式:000000000000 | 00000 | 000 | 00000 | 1110011
功能:调试断点,触发调试异常
CSRRW: csr | rs1 | 001 | rd | 1110011 # CSR读-写:rd = CSR; CSR = rs1
CSRRS: csr | rs1 | 010 | rd | 1110011 # CSR读-置位:rd = CSR; CSR |= rs1
CSRRC: csr | rs1 | 011 | rd | 1110011 # CSR读-清零:rd = CSR; CSR &= ~rs1
CSRRWI: csr | zimm | 101 | rd | 1110011 # CSR立即数读-写
CSRRSI: csr | zimm | 110 | rd | 1110011 # CSR立即数读-置位
CSRRCI: csr | zimm | 111 | rd | 1110011 # CSR立即数读-清零
说明:
- csr: 12位CSR地址
- zimm: 5位零扩展立即数
- 用于操作系统、异常处理、性能监控等
# B型指令立即数编码示例
def encode_b_imm(imm):
# 原始位: [12, 11:5, 4:1, 0] (最低位总是0)
# 编码位: [12, 10:5, 4:1, 11]
encoded = ((imm & 0x800) << 20) | # bit 12 -> bit 31
((imm & 0x7e0) << 20) | # bits 10:5 -> bits 30:25
((imm & 0x1e) << 7) | # bits 4:1 -> bits 11:8
((imm & 0x800) >> 4) # bit 11 -> bit 7
return encoded
# 构建32位常数
lui x5, 0x12345 # x5 = 0x12345000
addi x5, x5, 0x678 # x5 = 0x12345678
# 条件分支
loop:
addi x6, x6, -1
bne x6, x0, loop # x6 != 0时循环
# 函数调用
func:
# 保存寄存器
addi sp, sp, -16
sw x1, 12(sp)
# 函数体
# ...
# 返回
lw x1, 12(sp)
addi sp, sp, 16
jalr x0, 0(x1) # 返回