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

RISC-V C.SSPUSH 指令详解

指令手册C-type

C.SSPUSH 将固定的 x1 链接寄存器值压入向下增长的影子栈。

指令语法

c.sspush x1
操作数说明
该压缩形式固定为 x1,没有可变的显式寄存器操作数。
C.MOP.1 编码在 xSSE=1 时展开为 SSPUSH x1;ssp 是隐式基址,访问宽度为 XLEN。
xSSE=0 时不执行影子栈操作,C.MOP.1 不写寄存器。
ZicfissZcmop安全机制

指令行为说明

C.SSPUSH x1(Zicfiss,依赖 Zcmop)使用 C.MOP.1 编码,在 xSSE=1 时等价于 SSPUSH x1:向 ssp - XLEN/8 地址存储 x1 的值;只有存储成功后 ssp 才递减 XLEN/8 并提交更新。未启用 Zicfiss 时按 C.MOP.1 的 Zcmop 行为执行。

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

仅展示官方定义的编码、条件和架构可见结果,不表示微架构实现。

c.sspush x1

该压缩编码没有可变的显式寄存器:C.SSPUSH 固定 x1;C.SSPOPCHK 固定 x5。

执行环境
mem[0x0000000000001FF8] <- 0x0123456789ABCDEF; ssp <- 0x0000000000001FF8
16 位编码字段
15..13
funct3
011
12..11
fixed high bits
00
10..8
C.MOP.1 selector
000
7
fixed bit
1
6..2
fixed low bits
00000
1..0
op
01
固定压缩字段选择隐式寄存器。
address = 0x0000000000002000 - 8 = 0x0000000000001FF8; store 0x0123456789ABCDEF
mem[0x0000000000001FF8] <- 0x0123456789ABCDEF; ssp <- 0x0000000000001FF8
尚未提交架构状态。

快速理解与检索要点

C.SSPUSH 是固定 x1 的 Zicfiss 影子栈压入;只有 xSSE=1 且存储成功时才提交 ssp 递减。

影子栈操作隐式使用 ssp,宽度为 XLEN。
不要把 CFI MOP 兼容性误解为安全检查总是执行;xSSE=0 时这两个压缩 C.MOP 形式不访问影子栈且不写寄存器。

常见使用场景

函数调用与返回

使用 jal ra, label 或 jalr ra, rs, imm。

安全机制

结合 «c.sspush x1 # push ra onto shadow stack» 等实际代码理解该场景。

压缩与代码优化

结合 «c.sspush x1 # push ra onto shadow stack» 等实际代码理解该场景。

使用前检查清单

语法检查
  • 确认 16 位 C.MOP.1 固定选择 x1;该压缩形式没有可变显式寄存器。
  • 确认 Zicfiss、Zcmop 及其所依赖的 Zicsr、Zimop、Zaamo 可用,并且不在 M-mode 使用 Zicfiss。
语义检查
  • xSSE=1 时先以 XLEN/8 计算新 ssp,再向该地址存储 x1;只有存储完成后才提交 ssp。
  • xSSE=0 时按 C.MOP.1 行为,不执行影子栈访问且不写寄存器。

容易混淆 / 常见误区

压缩形式只提供 x1;完整 SSPUSH 支持 x1 和 x5。
Zicfiss 依赖 Zicsr、Zimop 和 Zaamo;压缩形式还需要 Zcmop。
M-mode 不支持使用 Zicfiss。
SSPUSH/C.SSPUSH 只有在影子栈存储成功后才递减 ssp。

常见问题

C.SSPUSH 未启用相关 CFI 时会怎样?

Zicfiss 指令按官方 Zimop/Zcmop 兼容规则退化,不执行影子栈检查或更新。

C.SSPUSH 的官方来源是什么?

RISC-V 非特权 ISA 的 Control-flow Integrity 章节定义 LPAD、SSPUSH、SSPOPCHK、SSRDP 和 SSAMOSWAP。