Linux x64:为什么r10来自系统调用中的r8和r9?

时间:2014-01-24 00:21:40

标签: linux assembly 64-bit

前几天我决定在装配上采取行动,我一直在玩一些非常基本的东西,比如从argv打印到stdout。我发现this great list of linux syscall numbers有参数和所有内容,我很好奇为什么r10用于r8r9之前的参数。我已经找到各种奇怪的约定,关于什么可以用于什么和何时,比如循环计数器如何进入rcxr10被提升的原因有什么特别的原因吗?它更方便吗?

我可能也应该提到我出于好奇而对此感兴趣,而不是因为它引起了我的问题。

修改:我发现this question已关闭,引用第124页的the x64 ABI documentation,其中注意到用户级应用程序使用rdi, rsi, rdx, rcx, r8, r9。另一方面,内核使用r10而不是rcx,并销毁rcxr11。这可能解释了r10如何在那里结束,但那为什么要交换?

2 个答案:

答案 0 :(得分:6)

RCX以及R11syscall指令使用,并立即被其销毁。因此,这些寄存器不仅不会在系统调用之后保存,而且甚至不能用于参数传递。因此,选择R10来替换不可用的RCX以传递第四个参数。

另请参阅this answer以获取有关syscall如何使用这些寄存器的更多信息。

参考:Intel's Instruction Set Reference,查找SYSCALL

答案 1 :(得分:0)

请参阅x86-64.orgs abi documentation page 124

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

  2.   
  3. 系统调用是通过syscall指令完成的。内核破坏了   注册%rcx和%r11。

  4.   

这就是说当你使用系统调用指令时,内核会销毁%rcx,所以你需要使用%r10


同样来自@technosaurus的评论解释说,如果在系统调用期间发生中断,内核正在使用%rcx来存储入口点