首页/指令库/C-ADDI16SP
C.ADDI16SP

RISC-V C.ADDI16SP 指令详解

指令手册C-type

将非零 6 位有符号立即数按 16 缩放后加到 x2/sp。16 位 CI 格式,与 C.LUI 共享编码空间。

操作数简记

C.ADDI16SP: nzimm (x2/sp fixed)
操作数说明
16 位 CI 格式;rd/rs1 固定为 x2/sp,不映射到 x8–x15。
非零立即数为 -512 到 496 的 16 字节倍数;零编码保留。
符号扩展后与旧 sp 相加,保留低 XLEN 位;对应 addi x2, x2, nzimm。
C压缩指令

指令行为说明

C.ADDI16SP 与 C.LUI 共享编码空间,但目标字段固定为 x2/sp。它把分散编码的非零 nzimm[9:4] 符号扩展后加到 x2/sp;该立即数表示 -512 到 496 的 16 字节倍数。它展开为 addi x2, x2, nzimm[9:4];nzimm=0 的编码保留。

C.ADDI16SP 指令解析与执行动画

固定读写 x2/sp,还原缩放立即数,再计算并提交 XLEN 位结果。

固定源和目的寄存器
x2 / sp
x2/sp: 0x00001000 + -32 → 0x00000FE0
0x713D = 0111000100111101 (CI)
funct3 [15..13]
011
nzimm[9] [12]
1
rd/rs1 [11..7]
00010 (x2/sp)
nzimm[4|6|8:7|5] [6..2]
01111
op [1..0]
01
nzimm[9:4] = 111110
符号扩展并缩放: -2 × 16 = -32
尚未计算

还原压缩操作数

rd/rs1 固定为 00010。inst[12] 和 inst[6:2] 拼回 nzimm[9:4];低四位为零,立即数符号扩展到 XLEN。

x2/sp = 0x00001000; PC = 0x00002000

假设 C 扩展可用且取指成功。教学步骤不表示处理器流水线或周期;16 的倍数会保持原有 sp 的低四位,不会修正未对齐的 sp。

快速理解与检索要点

C.ADDI16SP 是 16 位 C 扩展指令:固定读取并写回 x2/sp,将非零 nzimm[9:4] 符号扩展后相加。它只编码 -512 到 496 的 16 字节倍数。

funct3=011、op=01,rd 字段为 x2;nzimm 位按 [9]、[4|6|8:7|5] 分散编码。
nzimm=0 是保留编码,不应作为普通 C.ADDI16SP 计算或栈帧调整示例。

常见使用场景

函数调用与返回

函数序言或尾声可用非零的 16 倍数调整固定的 x2/sp;例如旧 sp=0x1000、nzimm=-32,成功后 sp=0x0fe0,等效于 addi x2, x2, -32。

使用前检查清单

语法检查
  • 确认 RV32C / RV64C 与 16 位指令编码条件。
  • 16 位 CI 格式;rd/rs1 固定为 x2/sp,不映射到 x8–x15。
语义检查
  • 非零立即数为 -512 到 496 的 16 字节倍数;零编码保留。
  • 符号扩展后与旧 sp 相加,保留低 XLEN 位;对应 addi x2, x2, nzimm。

容易混淆 / 常见误区

立即数必须是 -512 到 496 内的非零 16 字节倍数;nzimm=0 编码保留。
x2/sp 是编码固定的隐式源和目的寄存器,不是可选 rd。

常见问题

C.ADDI16SP 的立即数范围为何不是连续的每个整数?

该立即数按 16 字节缩放编码,因此只有 -512 到 496 之间的非零 16 字节倍数可编码。

nzimm=0 时会怎样?

C.ADDI16SP 仅在 nzimm 非零时有效;nzimm=0 的编码保留。