addi
lyszt.net 更详细地介绍了 addi 和其他 RISC-V 指令。
编码格式
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode
描述
addi 将一个常量加到一个寄存器上。这个名字代表 add immediate(立即数加法)。立即数是一个直接写在指令本身中的常量值,而不是从寄存器中读取的。当你在编写程序时其中一个数字是固定的,例如给计数器加 1,就可以使用它。
addi 的形式如下所示。它读取源寄存器 rs1 中的值,加上常量 imm,并将结果写入目标寄存器 rd。
addi rd, rs1, imm
下一行读取 t0,加一,并将结果写回,因此 t0 = t0 + 1。
addi t0, t0, 1
该常量占 12 位且为有符号,范围为 -2048 到 2047。汇编器会拒绝更大的值。对于更大的常量,先用 li 将其加载到寄存器中。负常量会使 addi 也执行减法,这就是 RISC-V 没有单独的 subtract-immediate 指令的原因。下一行进行递减。
addi t0, t0, -1
RISC-V 手册将该常量称为符号扩展的 12 位立即数。它指出算术溢出会被忽略,因此结果只保留其低 XLEN 位,其中 XLEN 是寄存器宽度(以位为单位),这里为 32。当常量的符号已知时,加法之后的一个分支会检查有符号溢出。下面两行处理加上正常量这一常见情况。
addi t0, t1, +imm blt t0, t1, overflow
程序使用 addi 来实现计数器、将指针移动到下一项以及在栈上预留空间。示例中加 1 来推进计数器,加 -16 来预留 16 字节的工作内存,这通常是需要工作空间的函数的开头方式。
示例
addi t0, t0, 1 # t0++ addi sp, sp, -16 # reserve 16 bytes of stack
简三的图詰
- [1]RISC-V International. The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture. Version 20260120. Section 2.4.1, Integer Register-Immediate Instructions, pages 28 to 29.
- [2]RISC-V International. The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture. Version 20260120. Section 2.4, Integer Computational Instructions, page 27.
