2012-05-17 119 views
3

我正在使用Apple的llvm-gcc編譯一些內聯彙編代碼。我寫了我希望它做的事,但它添加了不斷寫入變量的無關命令。爲什麼它這樣做,我該如何阻止它?爲什麼GCC添加彙編命令到我的內聯彙編?

實施例:

__asm__{ 
    mov r11, [rax] 
    and r11, 0xff 
    cmp r11, '\0' 
} 

變(在 「組件」 助理視圖):

mov 0(%rax), %r11  // correct 
movq %r11, -104(%rbp) // no, GCC, obviously wrong 
and $255, %r11 
movq %r11, -104(%rbp) 
cmp $0, %r11 

乾杯。

+3

您是否嘗試過使用[擴展asm語法](http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s5)設置適當的輸入,輸出和clobber列表? –

+0

@亞當,這是我最好的猜測......今天我會嘗試。我是否必須切換到'asm(「cmd1 \ n \ t」「cmd2」:...:...:...)樣式,或者是否有方法將分隔符添加到花括號表示中? –

+0

我不知道是否有方法使用大括號表示法來添加這些說明符;它不應該太難轉換爲使用帶引號的字符串。 –

回答

2

你需要使用GCC的extended asm syntax來告訴它你使用哪個寄存器作爲輸入和輸出以及哪些寄存器被破壞。如果你不這樣做,它不知道你在做什麼,它產生的程序集很容易干擾你的代碼。

通過通知它你的代碼在做什麼,它改變了它如何註冊分配和優化,並避免破壞你的代碼。

0

這是因爲gcc試圖優化你的代碼。您可以通過將-O0添加到命令行來阻止優化。

+0

對不起,我只是試過這個,你是不正確的。 –

0

嘗試在__asm__之後添加volatile,如果你不想要的話。額外的命令可能是上一個/下一個C指令的一部分。沒有易失性編譯器可以這樣做(因爲它可能以這種方式更快地執行 - 而不是你的代碼,整個例程)。

+0

在詢問之前,我做了一些Google搜索,這是第一個出現的問題。唉,編譯器忽略了它(併發出了這樣的警告)。我不認爲額外的命令來自函數的其他地方,因爲它將兩次移動到同一個內存中,從而有效地使第一個移動成爲一個nop。 –