2011-10-06 58 views
3

考慮下面的C程序:混亂上ARM9數據對齊

int main(void) 
{ 
    char string[10] __attribute__ ((aligned(32))); 
    int i; 
    int *intp = (int*)(string + 1); 

    printf("string: 0x%x, intp: 0x%x\n", string, intp); 

    for (i=0; i<10; i++) 
    { 
     string[i] = 10; 
    } 
    dump(string); 

    printf("*intp: 0x%x\n", *intp); 

    *intp = 0xEEEEEEEE; 
    dump(string); 

    return 0; 
} 

所以我基本上迫使CPU在未對齊的地址來訪問一個32位的數據(INT)。 TBH我希望在我的ARM9板上發生段錯誤。而是我得到了一些有趣的/令人困惑的結果:

設置INTP到0xEEEEEEEE後,字符串的傾銷顯示:

0xee, 0xee, 0xee, 0xee, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa  

因此,代碼實際上是在串改的第一要素!爲什麼?

感謝,

+0

只是好奇:會發生什麼,如果你嘗試'INT * INTP =(INT *)(字符串+ 2);'? +3怎麼樣? – cnicutar

+0

@cnicutar:其實+2或+3不會有所作爲! – lang2

回答

5

最有可能的CPU「四捨五入」未對齊的地址,這樣,當你通過未對齊的地址給某一指令,硬件查找最近的邊界,並執行該地址指定的操作。

This可能真正回答你的問題:

在ARM和StrongArm的,如果你問一個非對齊的字,你 不採取對齊陷阱,那麼你得到的字對齊旋轉 ,這樣您請求的字節對齊位於LSB中。例如,

Consider: 
     Address: 0 1 2 3 4 5 6 7 
     Value : 10 21 66 23 ab 5e 9c 1d 

Using *(unsigned long*)2 would give: 
     on x86: 0x5eab2366 
     on ARM: 0x21102366