SUB

RISC-V SUB 指令详解

指令手册R-type

从rs1减去rs2,结果写入rd

指令语法

sub rd, rs1, rs2
操作数说明
rd:接收低 XLEN 位差值,写入 x0 被丢弃。
rs1:被减数;rs2:减数,公式为 rs1-rs2。
源先读后写;RV32I/RV64I 分别使用 32/64 位。
RV32IRV64I算术运算

指令行为说明

SUB 使用 32 位 R-type 编码(opcode=0110011、funct3=000、funct7=0100000),计算 rs1-rs2,将低 XLEN 位写入 rd;算术溢出不触发异常。RV32I 使用 32 位,RV64I 使用 64 位。写入 x0 被丢弃。基础整数 ISA 无 SUBI;要减一个可编码常量,可用 ADDI 加其相反数,但相反数必须落在 -2048 到 2047。

SUB 指令解析与执行动画

RV32I/RV64I; XLEN-bit subtraction

sub rd, rs1, rs2

执行环境

假设取指成功、无异步中断及额外扩展检查;同名寄存器共用一份初值。

32-位编码0x40C58533
funct7 [31..25]
0100000
rs2 [24..20]
01100 → x12
rs1 [19..15]
01011 → x11
funct3 [14..12]
000
rd [11..7]
01010 → x10
opcode [6..0]
0110011
x11=0x00000014; x12=0x00000009
尚未计算

读取指令

解析当前指令字段并读取写回前源值;还没有提交结果。

x10=0x00000007; PC=0x00002000
当前架构状态(提交前)

这是架构效果的教学步骤,不代表处理器流水线或周期。

快速理解与检索要点

从rs1减去rs2,结果写入rd

先读取 rs1 和 rs2,再写入 rd;重叠寄存器读取同一旧值。
RV32I/RV64I 分别保留差值低 32/64 位。

常见使用场景

寄存器差值

RV32I/RV64I,x6=20、x7=7:sub x5, x6, x7 得到 x5=13;只保留低 XLEN 位。

取负

RV32I/RV64I,x7=7:sub x5, x0, x7 将 XLEN 位的 -7 写入 x5,等效于 neg x5, x7。

使用前检查清单

语法检查
  • 寄存器字段选择 x0–x31 或其 ABI 名称。
  • SUB 使用 rd、rs1、rs2,没有立即数。
语义检查
  • 计算 rs1-rs2,只保留低 XLEN 位。
  • 算术溢出不触发异常;x0 写入丢弃,重叠寄存器先读取旧值再写回。

容易混淆 / 常见误区

操作数顺序为 rs1-rs2。
仅保留低 XLEN 位;算术溢出不触发异常。
用 ADDI 减常量时,其相反数必须落在 -2048 到 2047。

常见问题

SUB 和 ADD 的编码差异是什么?

二者 opcode=0110011、funct3=000;SUB 的 funct7=0100000,ADD 为 0000000。

如何减去立即数 8?

写 addi rd, rs1, -8。ADDI 的有符号 12 位立即数必须为 -2048 到 2047;任意常量不能都用一条 ADDI 表示。