ra / x1 调用后会自动保持吗?
不会。psABI 标记 ra 调用后不保持;需要跨调用保留时必须显式保存。
ra 是 RISC-V 调用约定中的返回地址寄存器。JAL 或 JALR 以 x1 为目的寄存器时会将下一条指令地址写入 ra;ret 伪指令通过该地址返回。psABI 标记 ra 调用后不保持。
psABI 将 x1 命名为 ra,用于保存返回地址。它标记为调用后不保持;需要跨调用保留的值必须由代码显式保存。
ra / x1 是 psABI 的返回地址寄存器。使用 x1 作为链接目的寄存器的调用序列会把下一条指令地址写入这里;它不是调用后保持寄存器,需要跨调用保留的值必须显式保存。
jal / jalr 会把下一条指令地址写入 ra,除非 rd 不是 ra。
ret 展开为 jalr x0, 0(ra),依赖 ra 中的返回地址。
如果函数内部还会调用其他函数,保存和恢复 ra 是当前函数自己的责任。
addi sp, sp, -16
sd ra, 8(sp)
call foo # ra 会被覆盖;RV32 保存 32-bit 值时用 sw/lw
ld ra, 8(sp)
addi sp, sp, 16
ret不会。psABI 标记 ra 调用后不保持;需要跨调用保留时必须显式保存。
因为以 ra/x1 为链接目的寄存器的 JAL 或 JALR 会写入新的下一条指令地址,从而覆盖旧值。