gpt4 book ai didi

c++ - Win64 与系统 V ABI (x86_64) : Win64 Skipping registers?

转载 作者:太空宇宙 更新时间:2023-11-04 02:29:28 24 4
gpt4 key购买 nike

假设我们有一个具有以下签名的 C(或 C++)函数:

void foo(int64_t a, double b, int64_t c, double d);

在 Linux、Mac 或任何使用 System V ABI (x86_64) 的操作系统上编译时,acrdi 中通过和 rsi寄存器,和 bd获得通过 xmm0xmm1 .好吧,这没有错。但是后来我在 Windows (x86_64) 中做了同样的事情,看起来它跳过了一些寄存器。 ac获得通过 rcxr8 ( rdx 已跳过)和 bd获得通过 xmm1xmm3 ( xmm0xmm2 已跳过)。为什么 Win64 这样做而不是像 System V 那样“压缩”参数?使用 System V,我想象能够传递 4 个 qwords 和 4 个 double 字而不需要在堆栈上传递任何东西,而 Win64,正如我猜测的那样,会传递堆栈上第 4 个参数之后的任何东西。

我知道在 Win64 和 SysV 中传递参数的寄存器顺序的差异,但顺序不应该是相关的。我很好奇为什么 Win64 会跳过寄存器,尤其是当它只有 4 个用于非堆栈参数传递时。

最佳答案

微软的文档

https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160

表示它们在寄存器中最多传递 4 个参数。如果一个参数不适合特定寄存器,则跳过该寄存器。

“ float 和 double 参数在 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++ - Win64 与系统 V ABI (x86_64) : Win64 Skipping registers?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45699107/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com