根据System V X86-64ABI,应用程序中的函数调用使用以下寄存器序列传递整数参数:
rdi, rsi, rdx, rcx, r8, r9
但是系统调用参数(而不是系统调用号)在另一个寄存器序列中传递:
rdi, rsi, rdx, r10, r8, r9
为什么内核使用r10而不是rcx第四个参数?它与当下rcx没有保留的事实有某种联系r10吗?
r10
rcx
X86-64系统调用使用syscall说明。该指令将返回地址保存到rcx,然后rip从IA32_LSTARMSR 加载。即rcx立即被摧毁syscall。这就是为什么rcx必须替换系统调用ABI的原因。
syscall
rip
IA32_LSTAR
相同的syscall指令也保存rflags到中r11,然后rflags使用IA32_FMASKMSR 进行掩码。这就是为什么r11内核不保存它的原因。
rflags
r11
IA32_FMASK
因此,这些更改反映了系统调用机制的工作方式。这就是为什么内核被迫声明rcx并且r11未保存,甚至不能使用它们进行参数传递的原因。
参考:英特尔指令集参考,查找SYSCALL。
SYSCALL