SSPUSH

RISC-V SSPUSH 指令详解

指令手册SYSTEM (MOP.RR.7)

xSSE=1 时,SSPUSH 将 x1/x5 的值压入向下增长的影子栈。

指令语法

sspush rs2

RV32/RV64 Zicfiss(依赖 Zicsr、Zimop、Zaamo);sspush rs2,rs2 仅 x1/x5。

32 位 SYSTEM:bits31:25=1100111、rs1=00000、funct3=100、rd=00000、opcode=1110011,rs2 是源字段。

xSSE=1 时向 ssp−XLEN/8 存储 XLEN 位源值,存储成功后才提交新 ssp;不写源寄存器。

S-mode 已实现时,M 的 xSSE=0,S/HS 取 menvcfg.SSE、VS 取 henvcfg.SSE、U/VU 取 senvcfg.SSE;无 S-mode 时 M/U 均为 0。兼容行为要求支持 Zimop。xSSE=0 时不访问影子栈且不更新 ssp;活动时未按 XLEN 对齐产生 store/AMO access-fault。

Zicfiss安全机制

指令行为说明

xSSE=1 时,SSPUSH 以 ssp - XLEN/8 为地址把 x1 或 x5 的返回地址副本写入影子栈;只有影子栈存储成功后,ssp 才提交为该新值。它用于非叶子函数入口,配合普通栈保存返回地址来检测返回地址被篡改。

SSPUSH 指令解析与执行动画

只显示规范定义的编码、条件和架构可见状态。

sspush x1
sspush
执行环境

假定 Zicfiss 与 Zimop 已实现;xSSE 是当前模式按规范确定的启用状态。ssp 的低两位必须为零;RV64 允许 bit2=1 的输入假定实现也支持 32 位模式。complete 表示影子栈访问保护通过。步骤不代表处理器周期。

指令编码
31..25
MOP.RR.7
1100111
24..20
rs2
00001
19..15
rs1
00000
14..12
funct3
100
11..7
rd
00000
6..0
opcode
1110011 SYSTEM
解码固定字段
ssp=0x0000000000002000, x[x1]=0x0000000012345678
mem[0x0000000000001FF8] <- 0x0000000012345678; ssp <- 0x0000000000001FF8
尚未提交架构状态。

快速理解与检索要点

SSPUSH 是 Zicfiss 影子栈压入指令;只有完成存储后才更新 ssp。

隐式使用 ssp,访问宽度为 XLEN;xSSE=0 时不访问影子栈且不更新 ssp。
需要 Zimop 支持才能在 Zicfiss 未实现或未激活时提供 MOP 兼容行为;没有 Zimop 的处理器可能触发非法指令异常。

常见使用场景

函数调用与返回

假定 RV64 Zicfiss、S-mode、menvcfg.SSE=1(xSSE=1)、ssp=0x2000。x1=0x12345678,合法存储完成后 mem[0x1FF8]=0x12345678,ssp=0x1FF8。

影子栈检查与展开

假定 RV64 Zicfiss、S-mode、menvcfg.SSE=1(xSSE=1)、ssp=0x2000。x1=0x12345678,合法存储完成后 mem[0x1FF8]=0x12345678,ssp=0x1FF8。

使用前检查清单

语法检查
  • RV32/RV64 Zicfiss(依赖 Zicsr、Zimop、Zaamo);sspush rs2,rs2 仅 x1/x5。
  • 32 位 SYSTEM:bits31:25=1100111、rs1=00000、funct3=100、rd=00000、opcode=1110011,rs2 是源字段。
语义检查
  • xSSE=1 时向 ssp−XLEN/8 存储 XLEN 位源值,存储成功后才提交新 ssp;不写源寄存器。
  • S-mode 已实现时,M 的 xSSE=0,S/HS 取 menvcfg.SSE、VS 取 henvcfg.SSE、U/VU 取 senvcfg.SSE;无 S-mode 时 M/U 均为 0。兼容行为要求支持 Zimop。xSSE=0 时不访问影子栈且不更新 ssp;活动时未按 XLEN 对齐产生 store/AMO access-fault。

容易混淆 / 常见误区

该指令只支持 x1 或 x5 作为源链接寄存器。
Zicfiss 依赖 Zicsr、Zimop 和 Zaamo 扩展。
只有相应 Zicfiss 状态启用时才提供影子栈保护;未启用时按规范的兼容行为处理。
若隐式影子栈存储产生 store/AMO access-fault、页故障或来宾页故障,ssp 不更新。
若 ssp 未按 XLEN 对齐,SSPUSH 会产生 store/AMO access-fault。
访问内存必须是幂等的,并且 PMP 必须允许读写;否则会产生 store/AMO access-fault。
异常行为取决于当前特权级、环境配置 CSR 和页表/内存属性。
ssp 先递减形成存储地址,但只有存储成功后才提交更新。

常见问题

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

xSSE=0 时,SSPUSH 不访问影子栈且不更新 ssp。未实现 Zicfiss 但支持 Zimop 时也按 MOP 行为执行;没有 Zimop 支持则可能触发非法指令异常。

SSPUSH 的官方来源是什么?

The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture 的 Control-flow Integrity 章节定义此指令;Volume II: Privileged Architecture 定义启用状态与影子栈内存保护。