考慮下面的代碼:何時可以安全使用「= r」寄存器操作數約束?
#include <stdio.h>
void main() {
uint32_t num = 2;
__asm__ __volatile__ ("CPUID");
__asm__ __volatile__ ("movl $1, %%ecx":);
__asm__ __volatile__ ("andl $0, %%ecx": "=r"(num));
printf("%i\n", num);
}
我最初的預期是,該代碼將打印0
,如果我註釋掉CPUID
線確實如此,但,是它給我的垃圾。經過一些試驗,錯誤和研究後,我意識到我正在獲得一個隨機寄存器的價值。顯然GCC不會假定我想要執行語句的結果。
問題是,我已經看到(其他人的)代碼依賴於該語句正確地獲取AND的結果,而不管其他寄存器正在發生什麼。根據我的觀察,顯然這樣的代碼被打破了,"=r"
應該被替換爲"=c"
。
我的問題是,我們是否可以依靠"=r"
約束行爲一致或根據顯而易見的期望?或者GCC的實現過於不透明/怪異/其他,最好只是在任何情況下都避免它?
您使用的是哪個版本的gcc?還有什麼優化級別?還有你在用什麼操作系統? –
@Gabriel 4.5.3在Windows 7 x64 SP1的Cygwin中未指定優化級別。 –