The handling of unaligned addresses in load and store instructions depends on the ARM architecture version.
In ARMv7-A and ARMv7-R, the A bit in the System Control Register, SCTLR, controls whether alignment checking is enabled or disabled. In ARMv7-M, the UNALIGN_TRP bit, bit 3, in the Configuration and Control Register (CCR) controls this.
If alignment checking is enabled, all unaligned word and halfword transfers cause an alignment exception. If disabled, unaligned accesses are permitted for the LDR, LDRH, STR, STRH, LDRSH, LDRT, STRT, LDRSHT, LDRHT, STRHT, and TBH instructions. Other data-accessing instructions always cause an alignment exception for unaligned data.
For STRD and LDRD, the specified address must be word-aligned.
ARMv5 and earlier
For word transfers, you must ensure that addresses are 4-byte aligned. Otherwise, if alignment checking is enabled, an alignment exception occurs. If alignment checking is unavailable, or if it is available but disabled, the following occur:
For STR, LDR, STM, and LDM, the specified address is rounded down to a multiple of four.
Additionally, for LDR only:
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:
Bits[31:24] if bit of the address is 0.
Bits[15:8] if bit of the address is 1.
Addresses must be halfword-aligned for halfword transfers, and doubleword-aligned for doubleword transfers.
ARMv6 can be configured to support either the ARMv5 or ARMv7 alignment models, depending on the value of the U bit in the SCTLR. ARMv6-M faults all unaligned data accesses.
If all your data accesses are aligned, you can use the --no_unaligned_access command-line option to avoid linking in any library functions that support unaligned accesses.