addi

addi

RISC-V 汇编 参考

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