Linux x64:为什么r10在系统调用之前是r8和r9?

我决定在前一天在大会上采取一些措施,我一直在玩真正基本的东西,比如从argv到stdout的打印。 我发现了这个带有参数和所有内容的linux系统调用号码列表 ,我很好奇为什么在r8r9之前使用r10参数。 我发现了什么可以用什么什么什么什么的时候,像循环计数器在rcx各种古怪的约定。 是否有一个特别的原因,为什么r10被提升? 更方便吗?

我可能也应该提到我对这个好奇心感兴趣,而不是因为它导致我的问题。

编辑:我发现这个问题得到了closures,引用x64 ABI文档在页面124,它注意到用户级应用程序使用rdi, rsi, rdx, rcx, r8, r9 。 另一方面,内核使用r10而不是rcx ,并破坏rcxr11 。 这可能解释了r10如何在那里结束,但为什么它交换?

Solutions Collecting From Web of "Linux x64:为什么r10在系统调用之前是r8和r9?"

RCXR11一起被syscall指令使用,被它立即销毁。 因此这些寄存器不仅在系统调用后不被保存,而且甚至不能用于参数传递。 因此选择R10来取代不可用的RCX来通过第四个参数。

有关syscall如何使用这些寄存器的更多信息,另请参阅此答案 。

参考: 英特尔的指令集参考 ,寻找SYSCALL

请参阅x86-64.org的abi文档 page 124

  1. 用户级应用程序使用整数寄存器来传递序列%rdi,%rsi,%rdx,%rcx,%r8和%r9。 内核接口使用%rdi,%rsi,%rdx,%r10,%r8和%r9。

  2. 系统调用是通过系统调用指令完成的。 内核破坏寄存器%rcx和%r11。

这就是说当你使用syscall指令时,内核会破坏%rcx所以你需要使用%r10


此外,来自@technosaurus的评论解释说,内核正在使用%rcx来存储入口点 ,以防系统调用期间发生中断。