1

署名付き関数の場合:

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

Pairx64 でコンパイルした場合、関数が次のように、 のフィールドをレジスタ経由で渡したいと思います。

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

OSX 10.6 で x86_64 用の gcc 4.2.1 を使用してテストをコンパイルすると、逆アセンブリを調べると、これがまさに何が起こるかがわかります。ただし、Windows で x64 用の MSVC 2008 を使用してコンパイルすると、逆アセンブリPairにより、スタックに渡されたことが示されます。プラットフォーム ABI がこの最適化を妨げる可能性があることを理解しています。これを機能させることができる MSVC 固有の注釈、呼び出し規約、フラグ、またはその他のハックを知っている人はいますか?

ありがとうございました!

4

2 に答える 2

1

私の VS2008 x64 コンパイラは、あなたと同じことをしません。構造体は XMM レジスタに適合し、レジスタ内のペア オブジェクトのコピーへのポインターを渡します。

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

ここではスタックに何も渡されません。

于 2010-03-25T18:57:13.797 に答える
0

これを行うとどうなりますか?

   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) );
于 2010-03-25T18:42:56.587 に答える