gcc creates 'strd' instructions which are accessing non-double-word aligned addresses. This is forbidden accordingly ARM Reference Manual and causes an alignment exception: | 10.6.14 STRD | However, the address of the first of the two words is required to be | doubleword-aligned (that is, the address must be divisible by 8). Example: ------------ $ cat foo.c struct A { unsigned int a; unsigned long long l; }; int main() { extern struct A volatile *a; a->l = 0; } $ arm-xscale-linux-gnu-gcc -c -Os -mabi=aapcs -march=armv5te ./foo.c $ objdump -d foo.o foo.o: file format elf32-littlearm Disassembly of section .text: 00000000 <main>: 0: e59f3010 ldr r3, [pc, #16] ; 18 <.text+0x18> 4: e3a00000 mov r0, #0 ; 0x0 8: e5933000 ldr r3, [r3] c: e3a01000 mov r1, #0 ; 0x0 10: e1c300f8 strd r0, [r3, #8] 14: e12fff1e bx lr 18: 00000000 andeq r0, r0, r0 ------------ AAPCS requires only a 4-Byte alignment for data pointers, so the external 'a' might point to a non-8 divisible address. The resulting address at 10: is non-8 divisible too and will cause an alignment exception. ------------- $ $C-gcc -v Using built-in specs. Target: arm-xscale-linux-gnu Configured with: ../configure --prefix=/usr --build=i686-redhat-linux-gnu --host=i686-redhat-linux-gnu --target=arm-xscale-linux-gnu --with-sysroot=/usr/arm-xscale-linux-gnu/sys-root --disable-__cxa_atexit --enable-target-optspace --with-gnu-ld --disable-nls --infodir=/usr/share/info --mandir=/usr/share/man --enable-version-specific-runtime-libs --enable-languages=c,c++,java,objc --enable-shared --enable-threads --disable-multilib --with-cpu=xscale --enable-cxx-flags=-mcpu=xscale -fomit-frame-pointer Thread model: posix gcc version 4.1.0
Invalid. The AAPCS requires 8-byte alignment of double-word objects (and, recursively any object containing such an object). Your struct contains a long long, which is a double-word object. See http://www.arm.com/products/DevTools/ABI.html for details.