For processors based on ARMv5 or earlier, or ARMv6-M, you must ensure that addresses for 4-byte transfers are 4-byte word-aligned, and addresses for 2-byte transfers are 2-byte aligned. In ARMv6 and later, except ARMv6-M, unaligned accesses are permitted for LDR, LDRH, STR, STRH, LDRSH, LDRT, STRT, LDRSHT, LDRHT, STRHT, and TBH instructions, where the architecture supports the instruction.
On some ARM processors, you can enable alignment checking. Non word-aligned 32-bit transfers cause an alignment exception if alignment checking is enabled.
If all your accesses are aligned, you can use the --no_unaligned_access command line option, to avoid linking in any library functions that might have an unaligned option.
If a processor does not have alignment checking available and enabled:
For STR, the specified address is rounded down to a multiple of four.
For LDR:
The specified address is rounded down to a multiple of four.
Four bytes of data are loaded from the resulting address.
The loaded data is rotated right by one, two or three bytes according to bits [1:0] of the address.
For a little-endian memory system, this causes the addressed byte to occupy the least significant byte of the register.
For a big-endian memory system, it causes the addressed byte to occupy:
For STM, LDM, STRD, and LDRD, in ARMv6 and earlier architectures, the specified address is rounded down to a multiple of 4.
In ARMv7 some instructions will fault regardless of alignment checking.
See also