我不明白在RAX中不传递参数的好处在哪里。因为返回值位于RAX中,无论如何都会被调用者覆盖。
有人能解释一下吗?
我不明白在RAX中不传递参数的好处在哪里。因为返回值位于RAX中,无论如何都会被调用者覆盖。
有人能解释一下吗?
al=8
是安全的,并且不能通过设置al=0
来在堆栈上传递FP参数。)
为什么不使用r9b
,并将RAX用于第6个参数?或者在之前的某个参数中使用RAX?
因为在x86中,RAX有太多的隐式用途,而在设计调用约定时进行的实验(http://web.archive.org/web/20140414124645/http://www.x86-64.org/pipermail/discuss/2000-November/001257.html)发现使用RAX往往需要在调用者或被调用者中额外添加指令。例如,因为RAX通常是计算调用者中其他参数的一部分所需,或者在执行与其中一个参数相关的操作时需要RAX,然后代码继续使用以RAX传递的参数。
RAX用于rep stos
(gcc曾经更积极地使用它来内联memset),以及用于div
和扩展(单操作数)mul
/imul
,gcc用于编译时常量除法。(为什么GCC在实现整数除法时使用奇怪的数字进行乘法运算?)。cdqe
vs. movsxd rax, eax
(或任何其他寄存器之间)。或者 add eax, imm32
(没有 ModRM)vs. add r/m32, imm32
(或大多数其他 ALU 指令)。请参见我在Tips for golfing in x86/x64 machine code上的一个答案。原始 8086 缺少许多更长的非 AX 替代品,但在 8086 和 386 之间,添加了一些诸如 imul r32, r32
和 movsx
/movzx
的东西。其他仅限于 RAX 的指令在优化速度时不值得使用(例如 xlatb
、lodsd
),或者已经被 P6 / AMD64 扩展所淘汰(将 lahf
作为 FP 比较的一部分淘汰,并使用 SSE/SSE2 的 ucomisd
进行 FP 数学),或者是专门的指令,如 cmpxchg
或 cpuid
,对调用约定设计没有影响。编译器根本不使用像 aaa
这样的 BCD 指令,而 AMD64 已将其删除。
rdx
在 rcx
之前,因为在没有BMI2的情况下需要 cl
进行可变移位计数。这些可能比 mul
和 div
更常见,因为2操作数imul reg,reg
允许正常非扩展乘法而不破坏 RDX:RAX。rdi
和rsi
显然是出于内联memset
或memcpy
作为rep movs
的动机(即使在gcc执行这些操作时,在许多情况下这并不是一个好选择)。尽管rep
-字符串指令使用RCX作为计数器,但他们仍然发现将第三个参数传递到RDX而不是RCX平均可以节省指令,因此调用约定不能完全满足memcpy
成为rep stosb
/ret
的要求。RAX,RDX,RCX,RBX,RSI,RDI
,但他发现这不如其他选项好。(请参见上面链接的邮件列表消息)。
r0
)和PowerPC也是如此。其他架构(例如MIPS)则不是这样。但是所有这些体系结构都没有隐式使用大多数整数寄存器,通常只有链接寄存器和堆栈指针。
eax
。https://en.wikipedia.org/wiki/X86_calling_conventions#Borland_register - Alex Guteniev