2010-03-25 95 views
0

對於簽名功能:有沒有辦法讓MSVC在x64的寄存器中傳遞結構參數?

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

編譯在x64上,我想Pair的領域通過寄存器傳遞,因爲如果函數是:

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

編譯用gcc測試4.2.1對於OSX 10.6上的x86_64,我可以看到這正是通過檢查反彙編發生的情況。但是,在Windows上使用MSVC 2008 for x64進行編譯時,反彙編顯示Pair已在堆棧上傳遞。我知道平臺ABI可以阻止這種優化;有沒有人知道任何MSVC特定的註釋,調用約定,標誌,或其他黑客可以得到這個工作?

謝謝!

+0

您可以將指針傳遞給結構嗎?這可能是最簡單的解決方案。 – 2010-03-25 18:37:38

+0

也許試試'__fastcall'。我聽說它可以做註冊相關的事情。 – 2010-03-25 18:39:36

+0

如果你傳遞一個指向結構體的指針,那麼你仍然在執行商店(以填充結構體,它將駐留在調用者的堆棧框架上)並加載(讀取字段)。在無結構的「void f(void *,void *)」情況下,可能沒有這樣的負載。 – Luke 2010-03-25 18:42:28

回答

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)); 
+0

仍然支付商店/負載,請參閱關於該問題的第三條評論。 – Luke 2010-03-25 18:44:50

+0

即使使用第二種解決方案,也能看到它嗎? (我只是猜測,從來沒有在64位編碼這樣的事情) – 2010-03-25 18:47:29

+0

我認爲sizeof(無符號長)是4; sizeof(Pair)(包含兩個指針)是16.但是,如果是一個可移植的內建函數,它在gcc和MSVC上都是16字節,並且通過寄存器傳遞,那麼這可能會起作用。 (是否存在?)它還要求ABI允許將標量值在寄存器中分開。 – Luke 2010-03-25 18:49:23

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) 

沒有被傳遞在這裏。

+0

感謝您的回答!被調用程序的反彙編看起來是什麼樣子,如果它訪問結構體的某個字段?任何加載? – Luke 2010-03-25 19:01:32

+0

@Luke,請自己來看看它啓動調試器,點擊文本編輯器,然後選擇「轉到反彙編」,注意只看版本的構建代碼是有意義的 – 2010-03-25 19:07:30

+0

這就是我在問這個問題之前所做的,我之所以問你是因爲y我們的組裝看起來不同還不清楚被調用者將不會執行加載來訪問參數值。 – Luke 2010-03-25 19:10:25

相關問題