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

为何syscall指令会破坏rcx与r11寄存器?相关疑问解析

x86-64系统调用中rcx/r11被破坏的常见疑问解答

先给大家铺垫两个权威来源的信息:
来自《Low-Level Programming: C, Assembly, and Program Execution on Intel® 64 Architecture》的说明:

系统调用参数说明
系统调用的参数存储寄存器与函数调用不同:第四个参数存在r10中,而函数调用的第四个参数存于rcx中!原因是syscall指令会隐式使用rcx,且系统调用最多接受6个参数。

另外还有Stack Overflow上的权威回答:

系统调用通过syscall指令实现,该指令会破坏%rcx、%r11以及%rax寄存器,其余寄存器则会被保留。

接下来咱们逐个拆解你的疑问:

为什么syscall指令会破坏rcx和r11?

这是x86-64架构硬件层面的硬规定,和操作系统无关:

  • 执行syscall时,CPU会自动把当前的rip(也就是系统调用完成后要回到用户态继续执行的指令地址)存入rcx——内核需要这个地址来完成返回跳转,这一步是硬件强制做的,所以rcx必然被覆盖。
  • 同时,CPU会把当前的rflags(标志寄存器,记录着比如进位、零标志这些状态)存入r11,内核处理完系统调用后要恢复用户态的标志位,所以r11也会被硬件自动改写。
  • 至于rax,它本来就是用来传系统调用号的,返回时又用来存返回值,被覆盖是大家都默认的约定。

是否有破坏rcx/r11的特定系统调用列表?

完全没有!因为这是syscall指令本身的硬件行为,不管你调用哪个系统调用,只要用了syscall触发,rcx和r11都会被破坏。操作系统根本没法干预这个硬件机制——不管是read、write这种基础调用,还是更复杂的系统调用,只要走syscall入口,这俩寄存器肯定保不住。

这种破坏是否有相关约定?

必须有,这是x86-64系统调用ABI(应用二进制接口)里写得明明白白的规则:

  • 用户态程序在调用系统调用前,必须默认rcx、r11、rax会被破坏,如果这两个寄存器里有需要保留的数据,一定要在执行syscall之前先把它们压栈保存好。
  • 其他通用寄存器(比如rbx、rbp、r12到r15这些)则会被内核完整保留,系统调用结束后它们的值和调用前完全一致,这也是ABI的硬性约定。

是否存在不会破坏它们的系统调用?

不存在。只要是通过syscall指令触发的系统调用,这两个寄存器都会被硬件自动覆盖。不过有个非主流的例外:如果你用老式的32位系统调用入口int 0x80(x86-64下也能兼容使用),它不会破坏rcx和r11,但这种方式效率极低,而且传参规则和syscall完全不同,现在几乎没人用了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:43:03