Win64 与 System V ABI (x86_64):Win64 跳过寄存器?
Win64 vs System V ABI (x86_64): Win64 Skipping registers?
假设我们有一个具有以下签名的 C(或 C++)函数:
void foo(int64_t a, double b, int64_t c, double d);
在 Linux、Mac 或任何使用 System V ABI (x86_64)、a
和 [=13] 的 OS 上编译时=] 在 rdi
和 rsi
寄存器中传递,b
和 d
在 xmm0
和 xmm1
中传递。好吧,这没有错。但是后来我在 Windows (x86_64) 中做了同样的事情,看起来它跳过了一些寄存器。 a
和 c
在 rcx
和 r8
中传递(rdx
已跳过),b
和 d
在 [ 中传递=19=] 和 xmm3
(xmm0
和 xmm2
已跳过)。为什么 Win64 会这样做而不是 "compacting" 像 System V 这样的参数?使用 System V,我想象能够传递 4 个 qwords 和 4 个双精度字而不需要在堆栈上传递任何东西,而 Win64,正如我猜测的那样,会传递堆栈上第 4 个参数之后的任何东西。
我知道在 Win64 和 SysV 中传递参数的寄存器顺序的差异,但顺序不应该是相关的。我很好奇为什么 Win64 会跳过寄存器,尤其是当它只有 4 个用于非堆栈参数传递时。
Microsoft 的文档
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
表示他们在寄存器中最多传递 4 个参数。如果一个参数不适合特定寄存器,则跳过该寄存器。
"浮点和双精度参数在 XMM0 - XMM3(最多 4 个)中传递,整数槽(RCX、RDX、R8 和 R9)通常用于该基数槽被忽略(参见示例),反之亦然。"
链接页面上的示例 3 正是您的示例,并解释了您看到的效果:
func3(int a, double b, int c, float d);
// a in RCX, b in XMM1, c in R8, d in XMM3
所以他们最多使用 4 个参数寄存器,RCX 或 XMM0 中的第一个参数,RDX 或 XMM1 中的第二个参数,等等。
那为什么要这样做呢?也许将 8 个寄存器参数传递给函数的想法似乎并不是一个重要的用例。
假设我们有一个具有以下签名的 C(或 C++)函数:
void foo(int64_t a, double b, int64_t c, double d);
在 Linux、Mac 或任何使用 System V ABI (x86_64)、a
和 [=13] 的 OS 上编译时=] 在 rdi
和 rsi
寄存器中传递,b
和 d
在 xmm0
和 xmm1
中传递。好吧,这没有错。但是后来我在 Windows (x86_64) 中做了同样的事情,看起来它跳过了一些寄存器。 a
和 c
在 rcx
和 r8
中传递(rdx
已跳过),b
和 d
在 [ 中传递=19=] 和 xmm3
(xmm0
和 xmm2
已跳过)。为什么 Win64 会这样做而不是 "compacting" 像 System V 这样的参数?使用 System V,我想象能够传递 4 个 qwords 和 4 个双精度字而不需要在堆栈上传递任何东西,而 Win64,正如我猜测的那样,会传递堆栈上第 4 个参数之后的任何东西。
我知道在 Win64 和 SysV 中传递参数的寄存器顺序的差异,但顺序不应该是相关的。我很好奇为什么 Win64 会跳过寄存器,尤其是当它只有 4 个用于非堆栈参数传递时。
Microsoft 的文档
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
表示他们在寄存器中最多传递 4 个参数。如果一个参数不适合特定寄存器,则跳过该寄存器。
"浮点和双精度参数在 XMM0 - XMM3(最多 4 个)中传递,整数槽(RCX、RDX、R8 和 R9)通常用于该基数槽被忽略(参见示例),反之亦然。"
链接页面上的示例 3 正是您的示例,并解释了您看到的效果:
func3(int a, double b, int c, float d);
// a in RCX, b in XMM1, c in R8, d in XMM3
所以他们最多使用 4 个参数寄存器,RCX 或 XMM0 中的第一个参数,RDX 或 XMM1 中的第二个参数,等等。
那为什么要这样做呢?也许将 8 个寄存器参数传递给函数的想法似乎并不是一个重要的用例。