assembly - 为什么使用向量寄存器而不是将标准参数保存在堆栈中?

标签 assembly x86-64 calling-convention

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

最佳答案

显然,因为那是被叫方会寻找它们的地方。

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

请注意,只有 FP 值 在 XMM regs 中传递,对于非可变参数函数,这是调用者需要它们的地方。

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

旧的 GCC 过去常常制作执行计算跳转到一系列 movaps 存储的代码,以保存实际使用的 XMM regs。现代 GCC 只是通过 test/jcc 在 8 个商店的 block 上保存全部或不保存。对于较旧的 GCC,AL 必须在 [0..8] 中的 ABI 要求很重要,并且 breaking that could lead to wild jumps .对于现代 GCC,唯一可能发生的坏事是在有 FP args 时错误地传递 AL=0,因此该函数读取保存区域中留下的任何垃圾。


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

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

关于assembly - 为什么使用向量寄存器而不是将标准参数保存在堆栈中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70134875/

相关文章:

c++ - 导入二进制文件gnu-assembler时检查标签之间的距离

performance - AVX512中 "masked"存储的粒度是多少?

assembly - 0和双字0有什么区别?

caching - 我们可以在堆内存上使用非临时 mov 指令吗?

c - 为什么 llvm 和 gcc 在 x86 64 上使用不同的函数序言?

c# - 通过 asm DLL 中的 ref 指针取消引用 C#

windows-7 - Windows 7 上的程序集

x86-64 - 预取写入是否会影响单核性能?

c - 关于从 Assembly 调用 C 函数,反之亦然

c++ - std::function 如何知道调用约定?