为什么使用向量寄存器而不是将 stdargs 保存在堆栈中?

2 assembly x86-64 calling-convention

所以我正在阅读 SYSTEM V AMD64 ABI,其中写道我们必须使用向量寄存器来保存 stdargs 并设置AL为用于放置参数的寄存器的数量。
为什么需要使用向量寄存器?我们不能将它们放入堆栈并将AL寄存器设置为堆栈中的参数数量吗?

Pet*_*des 6

因为显然,这就是被调用者寻找它们的地方。

您是否想问为什么调用约定是这样设计的,而不是像我认为的 MacOS 那样对可变参数使用堆栈参数?(至少对于 AArch64,我忘记 MacOS 是否对 x86-64 进行了任何更改)

请注意,只有FP 值会在 XMM 寄存器中传递,这对于非可变参数函数来说是调用者想要它们的地方。

x86-64 SysV 只是传递参数,与非可变参数函数相同,使用 AL 作为优化,因此如果没有 FP 参数,被调用者可以避免将所有 8 个可能的参数传递寄存器转储到堆栈中。(您不能将 FP 参数放在堆栈上并传递 AL=0;被调用者不必支持根据传入的 AL 值在不同位置查找第一个 FP 可变参数。)

旧的 GCC 过去常常编写代码,通过计算跳转到一系列movaps存储中,以保存实际使用的 XMM 寄存器。现代 GCC 只是通过 test/jcc 对 8 个存储块进行全部保存或不保存。对于较旧的 GCC,ABI 要求 AL 必须位于 [0..8] 中,这一点很重要,打破这一点可能会导致疯狂跳跃。对于现代 GCC,唯一可能发生的坏事是当存在 FP 参数时错误地传递 AL=0,因此该函数会读取保存区域中留下的任何垃圾。


对于调用者来说,对于可变参数函数,甚至对于整数,在堆栈上传递 FP 可变参数可能会更好,这样它们就可以形成一个数组,该函数可以在没有一堆额外逻辑的情况下进行索引。

正如我提到的,我认为这就是 MacOS 在 ARM64 上所做的事情。