寄存器指南

RISC-V sp / x2 寄存器:栈指针、栈帧与 ABI 对齐规则

sp 是 RISC-V 标准调用约定使用的栈指针。标准 ABI 中栈向低地址增长;sp 在过程入口必须按 128-bit 边界对齐,并在执行期间保持对齐。

psABI:x2 的 ABI 名称是 sp,调用后保持。
psABI:标准 ABI 中栈向低地址增长,sp 需要 128-bit 对齐。
新手规则:只按栈帧规则移动 sp,返回前恢复;不要当普通临时寄存器。
物理编号 x2ABI 名 sp保存责任 调用后保持

psABI 将 sp 标记为调用后保持:函数返回时必须恢复其入口值。函数内调整 sp 建立栈帧时,仍须遵守标准 ABI 的栈对齐要求,即在过程入口及执行期间保持 128-bit 对齐。

角色
栈指针
调用约定
调用后保持
先记一句
标准 ABI 要求栈指针在过程入口按 128-bit 边界对齐,并在执行期间保持对齐。
psABI 规范依据

栈指针

psABI 将 x2 命名为 sp,并标记为调用后保持。函数可以在栈帧建立期间移动 sp,但返回前必须恢复到入口值。

调用后保持:是
RISC-V psABI integer register convention
快速理解与检索要点

sp / x2 是标准调用约定的栈指针。psABI 标记它调用后保持;函数可以移动 sp 建立栈帧,但返回前必须恢复,并保持标准 ABI 的 128-bit 对齐要求。

psABI 将 x2 命名为 sp,并标记为调用后保持。
标准 ABI 中栈向低地址增长,sp 在过程入口按 128-bit 边界对齐。

适合什么时候用

  • - 建立当前函数的栈帧,保存 ra、s* 寄存器和局部变量。
  • - 处理参数寄存器不够时放到栈上的额外参数。
  • - 在函数入口下移,在函数返回前恢复到入口值。

什么时候不要这样用

  • - 不要把 sp 当普通临时寄存器参与计算。
  • - 不要只调整 sp 不恢复,调用链和局部变量访问都会被破坏。

调用前后会发生什么

1

标准 ABI 要求栈指针在过程入口按 128-bit 边界对齐,并在执行期间保持对齐。

2

callee 可以移动 sp 建立栈帧,但返回前必须恢复。

3

调用其他函数前,当前函数应确保栈状态满足 ABI 要求。

一个满足 16 字节对齐的 RV64 示例

示例用于理解规则,不替代完整程序
addi sp, sp, -16
sd   ra, 8(sp)
sd   s0, 0(sp)
addi s0, sp, 16
...
ld   s0, 0(sp)
ld   ra, 8(sp)
addi sp, sp, 16
ret
1.RV64 示例:分配 16 字节栈空间(sp 向低地址移动)
2.保存返回地址 ra 到 sp+8
3.保存旧 frame pointer s0 到 sp+0
4.把 s0 设为 sp 加 16;这是示例选择的帧指针布局,不是所有过程的要求
5.函数体;具体局部变量和参数布局由代码与 ABI 规则决定
6.从 sp+0 恢复旧 s0
7.从 sp+8 恢复 ra
8.释放栈空间(sp 回退到调用者位置)
9.通过 ra 返回调用者

与其他寄存器的关系

sp vs s0/fp (帧指针)

sp 是 x2 栈指针,标准 ABI 中栈向低地址增长,过程入口的 sp 需要保持 128-bit 对齐。s0/fp 是 x8;psABI 规定帧指针是可选的,但如果存在,必须位于 x8/s0。两者都属于调用后保持的 ABI 状态,但 sp 负责栈位置,s0/fp 只在采用帧指针约定时承担帧指针角色。

栈指针的使用约束

不要把 sp 当普通临时寄存器使用。标准 ABI 要求它在过程入口按 128-bit 对齐并在执行期间保持对齐;手写代码调整 sp 时必须维持这些条件。

常见问题

RISC-V 标准 ABI 对 sp 有什么对齐要求?

标准 ABI 要求 sp 在过程入口按 128-bit 边界对齐,并在执行期间保持对齐。