首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Win64与系统V ABI (x86_64):Win64跳过寄存器?

Win64与系统V ABI (x86_64):Win64跳过寄存器?
EN

Stack Overflow用户
提问于 2017-08-15 18:23:04
回答 1查看 666关注 0票数 2

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

代码语言:javascript
复制
void foo(int64_t a, double b, int64_t c, double d);

在Linux、Mac或任何使用System ABI (x86_64)的操作系统上编译时,ac将在rdirsi寄存器中传递,而bd则在xmm0xmm1中传递。好吧,没什么不对的。但是,我在Windows (x86_64)中也这样做,看起来它跳过了一些寄存器。acrcxr8 (rdx跳过)中传递,bdxmm1xmm3中传递(xmm0xmm2跳过)。为什么Win64要这样做,而不是“压缩”像System这样的参数呢?对于System,我设想能够通过,比方说,4个qword和4个双倍,而不需要在堆栈上传递任何东西,而Win64,正如我猜测的那样,会传递超过堆栈上的第4个参数的任何内容。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-15 19:43:30

微软的文档

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

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

浮点和双精度参数在XMM0 - XMM3 (最多4)中传递,整数槽(RCX、RDX、R8和R9)通常用于忽略基数槽(见示例),反之亦然。

链接页面上的示例3正是您的示例,并解释了您所看到的效果:

代码语言:javascript
复制
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个寄存器参数传递给函数的想法似乎并不是一个重要的用例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45699107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档