2009-05-31 40 views
3

將程序集代碼嵌入到C/C++程序中時,可以通過使用推送指令(或指定編譯器支持的clobber列表支持它)來避免使用clobbering寄存器。將程序集嵌入到C中,編譯器爲您找到寄存器

如果你包含內聯程序集,並且希望避免推送和彈出clobbered寄存器的開銷,有沒有辦法讓gcc爲你選擇寄存器(例如,它知道沒有有用的信息)。

+0

請添加'家庭作業'標籤,同時請注意,這並不意味着它只是一個家庭作業的網站,因此您必須提供您目前爲止所提供的內容,供其他人蔘加並提供其餘的部分。 – none 2009-05-31 00:22:50

+0

不確定你的意思。這是一個理論問題,所以目前還沒有「代碼」。 – bugmenot77 2009-05-31 00:30:48

+3

爲什麼你認爲這是作業?我從來沒有做過功課,詢問我有關使用gcc的詳細信息。這是一旦你真正嘗試在現實世界中實現某些東西時所面臨的問題。 – nosatalian 2009-05-31 01:18:41

回答

9

是的。您可以指定您希望將特定變量(輸入或輸出)存儲在寄存器中,但不必指定寄存器。有關詳細說明,請參閱this document。從本質上講,內聯彙編如下:

asm("your assembly instructions" 
     : output1("=a"), // I want output1 in the eax register 
     output2("=r"), // output2 can be in any general-purpose register 
     output3("=q"), // output3 can be in eax, ebx, ecx, or edx 
     output4("=A") // output4 can be in eax or edx 
     : /* inputs */ 
     : /* clobbered registers */ 
    ); 
+0

謝謝!我實際上在發佈之前瀏覽了該文件,但錯過了它。現在花了很長時間來閱讀這些小部分,我可以看到爲什麼!這並不漂亮,但它的工作原理。再次感謝。 – bugmenot77 2009-05-31 00:42:24

0

Compiler intrinsics是混合彙編和C/C++代碼的一個非常有用的方式。它們是看起來像函數的聲明,但實際上是直接編譯到單個本地指令(通過編譯器內部的特殊情況)。這給了你在彙編工作中的大部分控制權,但是將寄存器着色和調度留給了編譯器。

一個好處是,你可以將一個普通的C變量傳遞給一個內部函數,讓編譯器負責將其加載到寄存器上並調度其他操作。例如,

struct TwoVectors 
{ 
    __m128 a; __m128b; 
} 

// adds two vectors A += B using the native SSE opcode 
inline void SimdADD(TwoVectors *v) 
{ 
    v->a = _mm_add_ps(v->a , v->b); // compiles directly to ADDSS opcode 
} 
0

OK,所以我不能發表評論上面,但我敢肯定,正確的語法(與上面所述的不同)是:

asm ("your assembly instructions" 
    : "=a"(output1), 
     "=r"(output2), 
     "=q"(output3), 
     "=A"(output4) 
    : /* inputs */ 
    : /* clobbered registers */ 
); 

雖然你可以將輸入和輸出寄存器分配給編譯器,但沒有明顯的方式將劃分/臨時寄存器(即,用於中間值而不是輸入或輸出)分配給編譯器。歷史上,我只是在clobber列表中明確列出了它們(例如「%xmm1」,「%rcx」),但我現在認爲將它們列爲輸出以便編譯器選擇它們可能會更好。我不知道任何來源明確地解決這個問題。

相關問題