为什么系统调用寄存器和顺序从Intel 32bit 变成了64bit?

Eva*_*oll 6 linux system-calls history

我正在努力记住 Linux 系统调用的顺序,以便我可以更轻松地识别这一点。然后我在这里找到了这篇论文,它说,

要在32位Linux系统调用,将系统中的电话号码eax,然后它的参数,以便在ebxecxedxesiedi,和ebp,然后调用INT 0x80的。

进而,

要在64位Linux系统调用,将系统中的电话号码rax,然后它的参数,以便在rdirsirdxr10r8,和r9,然后调用系统调用。

为什么订单在 64 位和 32 位之间变得如此残缺?我知道这个问题可能是历史问题而不是技术问题。

这完全由内核决定,对吧?是否有技术原因支持较新的约定?

Ste*_*itt 8

这在很大程度上取决于内核,但是有一个很好的理由在 64 位 x86 上使用所选的调用约定:它匹配所选的用户空间约定。System V的X86-64 ABI,这是Linux使用,指定其功能使用的寄存器%rdi%rsi%rdx%rcx%r8,和%r9来传递参数。系统调用约定与此非常接近:唯一的区别是它使用的是%r10代替%rcx,主要是因为SYSCALL用于调用系统调用的新 64 位指令需要%rcx用于其他目的。


Rui*_*iro 0

编译代码中的寄存器顺序是Linux的一种调用约定,以方便生成和调试代码。

amd-64 架构比 32 位架构拥有更多的寄存器,并且使用新的调用约定来释放其他寄存器,以更好地优化代码。

如果您反汇编两种架构之间的代码,您还会注意到,在 amd-64 中,您经常会看到更多寄存器取代了函数中的局部整数变量。如果我没记错的话,rebp 用于优化在从函数返回之前使用局部变量堆栈生成的代码。