Ily*_*hin 6 x86-64 calling-convention
我不明白不在 RAX 中传递参数有什么好处,因为返回值在 RAX 中,无论如何它都会被被调用者破坏。
有人可以解释一下吗?
x86-64 System V确实将 AL 用于可变参数函数:调用者在 XMM 寄存器中传递 FP 参数的数量。
\n\n(这只是一种优化,允许被调用者不将所有向量寄存器转储到数组中;AL 中的数量允许高于 FP 参数的数量。在实践中,gcc 的可变参数函数的代码生成只是检查它是否非零,并转储 xmm0..7 的任何 8 个或全部 8 个。我认为 ABI 保证al=8即使实际上没有任何 FP 参数,它始终可以安全地通过,并且您无法通过设置在堆栈上传递传递 FP args al=0)
但为什么不使用r9b它,而使用 RAX 作为第 6 个参数呢?或者 RAX 对于一些早期的参数?
因为 RAX 在 x86 中有很多隐式用途,并且在设计调用约定时进行了实验(http://web.archive.org/web/20140414124645/http://www.x86-64.org/pipermail/discuss/2000- November/001257.html)发现使用 RAX 往往需要调用者或被调用者提供额外的指令。例如,因为在调用者中计算其他参数时通常需要 RAX,或者在代码开始使用 RAX 中传递的参数之前对其他参数之一执行某些操作时需要 RAX。
\n\nRAX 用于rep stos(gcc 过去更积极地使用内联 memset),它用于div和加宽(单操作数)mul/ imul,gcc 用于除以编译时常量。(为什么GCC在实现整数除法时使用乘以奇怪的数字?)。
大多数其他 RAX 特殊用途只是您也可以使用其他寄存器执行的操作的较短编码,例如cdqevs movsxd rax, eax(或任何其他寄存器之间)。或者add eax,imm32(无 ModRM)与add r/m32, imm32(或大多数其他 ALU 指令)。请参阅我在 \n Tips for Golfing in x86/x64 machine code上的答案之一。最初的 8086 缺乏许多更长的非 AX 替代品,但在 8086 和 386 之间,添加了像imul r32,r32and movsx/这样的东西。movzx其他仅 RAX 的指令在优化速度时不值得使用(例如xlatb、lodsd),或者被 P6 / AMD64 扩展废弃(lahf作为 FP 的一部分,被fucomiSSE/SSE2 废弃并用于ucomisdFP 数学),或者是专用指令likecmpxchg或cpuid太罕见,不会对调用约定设计产生影响。无论如何,编译器并没有使用 BCD 指令aaa,AMD64 删除了它们。
x86-64 System V 调用约定的设计者(主要是用于整数参数传递寄存器设计的 Jan Hubi\xc4\x8dka)通常旨在避免具有许多/常见隐式用途的寄存器。 在参数传递顺序中rdx位于前面,因为需要可变移位计数(没有 BMI2)。这些可能比和更常见,因为 2 操作数允许正常的非加宽乘法,而不会破坏 RDX:RAX。rcxclmuldivimul reg,reg
选择rdiandrsi作为前 2 个参数显然是由内联memset或memcpyas驱动的rep movs(gcc 在 2000 年就这样做了,尽管在 gcc 这样做的许多情况下实际上并不是一个好的选择)。尽管rep-string 指令使用 RCX 作为计数器,但它们仍然发现平均保存的指令是在 RDX 而不是 RCX 中传递第三个参数,因此调用约定不太memcpy适合rep stosb/ ret。
Jan Hubi\xc4\x8dka 通过使用当时版本的 x86-64 gcc 编译 SpecInt 来评估 arg 传递寄存器的多个变体。请参阅我的回答Why does Windows64 use a different call conventions from all other OSes on x86-64? 了解更多详细信息和链接。
\n\n他评估的 arg-register 命令之一是RAX, RDX, RCX, RBX, RSI, RDI,但他发现它不如其他选项好。(请参阅上面链接的邮件列表消息)。
RISC 调用约定在第一个返回值寄存器中传递第一个参数是相当常见的。ARM 做到了这一点(r0),我认为 PowerPC 也是如此。其他的(如 MIPS)则不然。但所有这些架构都没有隐式使用大多数整数寄存器,通常只是链接寄存器,也可能是堆栈指针。
x86-64 SysV 和 Windows 对 FP 参数执行此操作:xmm0 用于传递和返回。
\n| 归档时间: |
|
| 查看次数: |
773 次 |
| 最近记录: |