前几天我决定在装配上采取行动,我一直在玩一些非常基本的东西,比如从argv打印到stdout。我发现this great list of linux syscall numbers有参数和所有内容,我很好奇为什么r10
用于r8
和r9
之前的参数。我已经找到各种奇怪的约定,关于什么可以用于什么和何时,比如循环计数器如何进入rcx
。 r10
被提升的原因有什么特别的原因吗?它更方便吗?
我可能也应该提到我出于好奇而对此感兴趣,而不是因为它引起了我的问题。
修改:我发现this question已关闭,引用第124页的the x64 ABI documentation,其中注意到用户级应用程序使用rdi, rsi, rdx, rcx, r8, r9
。另一方面,内核使用r10
而不是rcx
,并销毁rcx
和r11
。这可能解释了r10
如何在那里结束,但那为什么要交换?
答案 0 :(得分:6)
RCX
以及R11
由syscall
指令使用,并立即被其销毁。因此,这些寄存器不仅不会在系统调用之后保存,而且甚至不能用于参数传递。因此,选择R10
来替换不可用的RCX
以传递第四个参数。
另请参阅this answer以获取有关syscall
如何使用这些寄存器的更多信息。
参考:Intel's Instruction Set Reference,查找SYSCALL
。
答案 1 :(得分:0)
请参阅x86-64.orgs abi documentation page 124
用户级应用程序用作整数寄存器来传递序列 %rdi,%rsi,%rdx,%rcx,%r8和%r9。内核接口使用%rdi, %rsi,%rdx,%r10,%r8和%r9。
- 醇>
系统调用是通过syscall指令完成的。内核破坏了 注册%rcx和%r11。
这就是说当你使用系统调用指令时,内核会销毁%rcx
,所以你需要使用%r10
。
同样来自@technosaurus的评论解释说,如果在系统调用期间发生中断,内核正在使用%rcx
来存储入口点。