You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RISC-V内核空间调用约定是否存在?ecall后寄存器状态问询

RISC-V ecall 执行后的寄存器状态规则

核心结论

  • 调用者保存寄存器(t0-t6):内核会完整保留这些寄存器的值,用户态代码在执行ecall前后无需手动保存/恢复,可以直接使用。这就是你在glibc的__open64_nocancel中看到ecall后直接用t3访问内存的原因——t3属于这类寄存器,内核不会修改它。
  • 参数/返回寄存器(a0-a7):
    • a0、a1:会被内核覆盖,用来存储系统调用的返回结果(a0是主返回值,a1为可选辅助返回值)。
    • a2-a7:内核不保证保留其原值,这些寄存器可能被内核任意修改,ecall后不能再假设它们还持有调用前的参数值。
  • 被调用者保存寄存器(s0-s11):内核同样会保留这些寄存器的值,跨ecall后可以安全使用。

对glibc代码示例的解释

你看到的这段指令:

ada22:       000e3783                ld      a5,0(t3)

t3属于调用者保存寄存器,根据RISC-V系统调用的寄存器约定,内核处理ecall时不会改动它的值,所以ecall结束后t3仍然持有之前的地址,直接用来访问内存是安全的。

澄清误区

你之前认为“所有临时寄存器都会被破坏”的认知,只适用于用户态函数调用的临时寄存器规则。系统调用的寄存器行为有明确区分:内核会维护调用者保存和被调用者保存寄存器的状态,仅会修改a0-a1用于返回,同时a2-a7的内容无法保证留存。

内容的提问来源于stack exchange,提问作者SilenceDesigner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:40:01