为什么 RCX 不用于将参数传递给系统调用,而是用 R10 代替?

Why is RCX not used for passing parameters to system calls, being replaced with R10?

根据 System V X86-64 ABI,应用程序中的函数调用使用以下寄存器序列来传递整数参数:

rdi, rsi, rdx, rcx, r8, r9

但是系统调用参数(系统调用号除外)在另一个寄存器序列中传递:

rdi, rsi, rdx, r10, r8, r9

为什么内核使用 r10 而不是 rcx 作为第四个参数?它是否与 rcx 未保留而 r10 保留的事实有某种关系?

X86-64系统调用使用syscall指令。该指令将 return 地址保存到 rcx,然后从 IA32_LSTAR MSR 加载 rip。 IE。 rcx 立即被 syscall 摧毁。这就是为什么必须为系统调用 ABI 替换 rcx 的原因。

同样的 syscall 指令也将 rflags 保存到 r11,然后使用 IA32_FMASK MSR 屏蔽 rflags。这就是 r11 没有被内核保存的原因。

因此,这些更改反映了系统调用机制的工作方式。这就是为什么内核被迫声明 rcxr11 不保存,甚至不能使用它们进行参数传递。

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