2012-02-16 66 views
1

我有一個問題,其中2個不同的編譯器(GCC和IAR)從不同大小的變量中刪除我的掩碼。爲什麼C編譯器會丟棄我的&0xFF掩碼?

我有以下代碼:

uint8_t Value2; 
uint16_t WriteOffset; 
bool Fail; 

void test(void) 
{ 
     uint8_t buff[100]; 
     uint16_t r; 

     for(r=0;r<Value2+1;r++) 
     { 
       if(buff[r]!=(WriteOffset+r)&0xFF) 
       { 
         Fail=true; 
       } 
     } 
} 

的如果失敗(進入{}塊)時buff[r] == 0和WriteOffset+r == 0x100的。

GCC輸出以下組件:

movzwl -0xc(%ebp),%eax       ; Load 'r'->EAX 
mov -0x70(%ebp,%eax,1),%al     ; Load 'buff[r]'->AL 
movzbl %al,%edx         ; Move AL to (unsigned int)EDX 
mov 0x4b19e0,%ax        ; Load 'WriteOffset'->AX 
movzwl %ax,%ecx         ; Move AX to (unsigned int)ECX 
movzwl -0xc(%ebp),%eax       ; Load 'r'->EAX 
lea (%ecx,%eax,1),%eax      ; 'WriteOffset' + 'r'->EAX 
cmp %eax,%edx        ; (unsigned int)'WriteOffset+r' == (unsigned int)'buff[r]' 
je  0x445e28 <Test+1254>      ; If == skip {} block 

我的問題是爲什麼編譯下降我&0xFF從IF(我已經固定鑄造的問題,但我還是不明白爲什麼它下跌它在第一個地方)?

+0

你在編譯什麼優化級別?總是重要的,特別是在添加裝配時。 – Joe 2012-02-16 22:09:39

+2

繼續學習C :) :) – 2012-02-16 22:23:42

回答

14

實在不行,operator precedence這裏咬你

你想if(buff[r] != ((WriteOffset+r)&0xFF))

什麼您目前擁有的是優先混亂導致你掩蓋一個值,可以在相同的if((buff[r]!=(WriteOffset+r)) & 0xFF)

只有0或1(比較表達式的結果)與0xFF,所以優化器是相當合理地刪除它。

+2

值得指出的是,位運算符'&','''和'^'的低前值是因爲在邏輯運算符之前將'&'和'|'添加到語言'&&'和'||',所以它們最初也用於邏輯表達式 - 低優先級通常是您想要的。 – caf 2012-02-17 03:38:07

+0

謝謝,我從未想過&和|比!=更低的優先級,但現在這一切都有意義。 – 2012-02-17 15:41:08

3

運營商!=的優先級高於&。所以你應該這樣寫:

if(buff[r]!=((WriteOffset+r)&0xFF)) 
相關問題