在有些處理器上,如果在非對齊地址上存取一個一個值,可能會出“對齊異常”。 比如,4字節的int型一般都要在能被4整除的地址上存取;2字節的short型在偶數地址上被存取。 gcc有編譯選項可以讓用戶指明代碼將要運行的主機是嚴格對齊的、還是支持非對齊操作。 這個選項就是 -mstrict-align 或 -mono-strict-align。
這是測試代碼:
struct tt
{
char first;
int second;
} __attribute__ ((packed));
struct tt b;
void foo(int p)
{
b.second = p;
}
我們申明瞭一個結構tt,注意它的整型成員 second 沒有放在“自然位置”(因爲packed的緣故),即能被它的長度4整除的位置。 然後我們在函數 foo 裏對該成員賦值。 如果用 -mno-strict-align , 目標機是PowerPc, 編譯出的代碼較簡單:
test.o: file format elf32-powerpc
Disassembly of section .text:
00000000 <foo>:
0: 94 21 ff e0 stwu r1,-32(r1)
4: 93 e1 00 1c stw r31,28(r1)
8: 7c 3f 0b 78 mr r31,r1
c: 90 7f 00 08 stw r3,8(r31)
10: 3d 20 00 00 lis r9,0
14: 39 69 00 00 addi r11,r9,0
18: 80 1f 00 08 lwz r0,8(r31)
1c: 90 0b 00 01 stw r0,1(r11) <- un-aligned access
20: 81 61 00 00 lwz r11,0(r1)
24: 83 eb ff fc lwz r31,-4(r11)
28: 7d 61 5b 78 mr r1,r11
2c: 4e 80 00 20 blr
我們看到, 對 b.second 的存取, 直接用 store word 指令在 r11 + 1 的位置完成了, 而 r11 + 1 其實是非4字節對齊的。 至於這樣做到底對不對,是由目標機硬件決定的, 開發者應該心中有數。
如果使用“-mstrict-align”,編譯器假定所有存取必須對齊,生成的代碼會複雜得多。 這裏就不列出了。