有没有办法让 MSVC 在 x64 上的寄存器中传递结构参数?

发布于 2024-08-26 05:23:03 字数 408 浏览 5 评论 0原文

对于具有签名的函数:

struct Pair { void *v1, *v2 };
void f(Pair p);

在 x64 上编译,我希望通过寄存器传递 Pair 的字段,就好像该函数是:

void f(void *v1, void *v2);

在 OSX 10.6 上使用 gcc 4.2.1 for x86_64 编译测试一样,通过检查反汇编,我可以看到这正是发生的情况。但是,在 Windows 上使用 MSVC 2008 for x64 进行编译时,反汇编显示 Pair 在堆栈上传递。我了解平台 ABI 可以阻止这种优化;有谁知道任何 MSVC 特定的注释、调用约定、标志或其他可以让它工作的技巧吗?

谢谢你!

For a function with signature:

struct Pair { void *v1, *v2 };
void f(Pair p);

compiled on x64, I would like Pair's fields to be passed via register, as if the function was:

void f(void *v1, void *v2);

Compiling a test with gcc 4.2.1 for x86_64 on OSX 10.6, I can see this is exactly what happens by examining the disassembly. However, compiling with MSVC 2008 for x64 on Windows, the disassembly shows that Pair is passed on the stack. I understand that platform ABIs can prevent this optimization; does anyone know any MSVC-specific annotations, calling conventions, flags, or other hacks that can get this to work?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

和我恋爱吧 2024-09-02 05:23:03

我的 VS2008 x64 编译器不会执行与您相同的操作。该结构适合 XMM 寄存器,它传递一个指向寄存器中pair对象副本的指针:

    Pair p;
    f(p);
000000013F2B1189  movaps      xmm6,xmmword ptr [p] 
000000013F2B118E  lea         rcx,[p] 
000000013F2B1193  movdqa      xmmword ptr [p],xmm6 
000000013F2B1199  call        f (13F2B1000h) 

这里没有在堆栈上传递任何内容。

My VS2008 x64 compiler doesn't do the same thing yours does. The struct fits in an XMM register, it passes a pointer to the copy of the pair object in a register:

    Pair p;
    f(p);
000000013F2B1189  movaps      xmm6,xmmword ptr [p] 
000000013F2B118E  lea         rcx,[p] 
000000013F2B1193  movdqa      xmmword ptr [p],xmm6 
000000013F2B1199  call        f (13F2B1000h) 

Nothing is passed on the stack here.

两个我 2024-09-02 05:23:03

如果你这样做怎么办?

   void f( void *ps ){
       struct Pair *p = (struct Pair *)ps;
   }

或者

void f( unsigned long addr ){
    struct Pair *p = (struct Pair *)addr;
}

struct Pair pp;

f( reinterpret_cast<unsigned long>(&pp) );

what if you do this ?

   void f( void *ps ){
       struct Pair *p = (struct Pair *)ps;
   }

or

void f( unsigned long addr ){
    struct Pair *p = (struct Pair *)addr;
}

struct Pair pp;

f( reinterpret_cast<unsigned long>(&pp) );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文