將程序集代碼嵌入到C/C++程序中時,可以通過使用推送指令(或指定編譯器支持的clobber列表支持它)來避免使用clobbering寄存器。將程序集嵌入到C中,編譯器爲您找到寄存器
如果你包含內聯程序集,並且希望避免推送和彈出clobbered寄存器的開銷,有沒有辦法讓gcc爲你選擇寄存器(例如,它知道沒有有用的信息)。
將程序集代碼嵌入到C/C++程序中時,可以通過使用推送指令(或指定編譯器支持的clobber列表支持它)來避免使用clobbering寄存器。將程序集嵌入到C中,編譯器爲您找到寄存器
如果你包含內聯程序集,並且希望避免推送和彈出clobbered寄存器的開銷,有沒有辦法讓gcc爲你選擇寄存器(例如,它知道沒有有用的信息)。
是的。您可以指定您希望將特定變量(輸入或輸出)存儲在寄存器中,但不必指定寄存器。有關詳細說明,請參閱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 */
);
謝謝!我實際上在發佈之前瀏覽了該文件,但錯過了它。現在花了很長時間來閱讀這些小部分,我可以看到爲什麼!這並不漂亮,但它的工作原理。再次感謝。 – bugmenot77 2009-05-31 00:42:24
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
}
OK,所以我不能發表評論上面,但我敢肯定,正確的語法(與上面所述的不同)是:
asm ("your assembly instructions"
: "=a"(output1),
"=r"(output2),
"=q"(output3),
"=A"(output4)
: /* inputs */
: /* clobbered registers */
);
雖然你可以將輸入和輸出寄存器分配給編譯器,但沒有明顯的方式將劃分/臨時寄存器(即,用於中間值而不是輸入或輸出)分配給編譯器。歷史上,我只是在clobber列表中明確列出了它們(例如「%xmm1」,「%rcx」),但我現在認爲將它們列爲輸出以便編譯器選擇它們可能會更好。我不知道任何來源明確地解決這個問題。
請添加'家庭作業'標籤,同時請注意,這並不意味着它只是一個家庭作業的網站,因此您必須提供您目前爲止所提供的內容,供其他人蔘加並提供其餘的部分。 – none 2009-05-31 00:22:50
不確定你的意思。這是一個理論問題,所以目前還沒有「代碼」。 – bugmenot77 2009-05-31 00:30:48
爲什麼你認爲這是作業?我從來沒有做過功課,詢問我有關使用gcc的詳細信息。這是一旦你真正嘗試在現實世界中實現某些東西時所面臨的問題。 – nosatalian 2009-05-31 01:18:41