为什么 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
没有被内核保存的原因。
因此,这些更改反映了系统调用机制的工作方式。这就是为什么内核被迫声明 rcx
和 r11
不保存,甚至不能使用它们进行参数传递。
参考:Intel's Instruction Set Reference,寻找SYSCALL
.
根据 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
没有被内核保存的原因。
因此,这些更改反映了系统调用机制的工作方式。这就是为什么内核被迫声明 rcx
和 r11
不保存,甚至不能使用它们进行参数传递。
参考:Intel's Instruction Set Reference,寻找SYSCALL
.