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

Linux x86-64系统调用何时会破坏%r8、%r9和%r10寄存器?

结论

标准x86_64 Linux的系统调用ABI明确承诺,syscall执行过程中只会破坏%rax(存储返回值)、%rcx(存储用户态返回地址,由syscall硬件指令自动写入)、%r11(存储调用前的rflags寄存器值,同样由硬件自动写入)三个寄存器,包括%r8、%r9、%r10在内的其余寄存器都会被内核保留,执行完系统调用后原值不变。

nolibc加入冗余clobber的原因

你观察到的nolibc头文件里把%r8、%r9、%r10加入clobber列表属于防御性编程的冗余写法,没有对应的常规系统调用场景会真的修改这三个寄存器,这么做的原因主要有两个:

  • 历史实现兼容:早期版本的nolibc系统调用宏没有为6参数系统调用正确配置%r8、%r9的输入寄存器绑定,宏内部会隐式使用这两个寄存器传递参数,加入clobber列表是为了告知GCC不要在这两个寄存器中存储需要跨系统调用保留的变量,避免变量被意外覆盖。
  • 兼容性优先的设计取向:nolibc的设计目标是极简、高兼容性,冗余的clobber声明虽然会略微损失生成代码的执行效率,但可以规避不同GCC版本、不同内核配置下的潜在边界问题,比如部分小众内核调试功能可能修改这几个寄存器的场景。

非常规的破坏场景

只有在引入外部干预的场景下才可能出现系统调用后%r8、%r9、%r10值被修改的情况,最典型的就是使用ptrace工具跟踪、修改系统调用上下文,这属于调试类的特殊操作,不属于普通用户态程序的常规执行逻辑,也不违反系统调用的ABI约定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 17:57:04