I ' m confused about unaligned memory accesses on ARM.
My understanding was, they ' re isn't allowed-that is,
Dereferencing a 32-bit value from a pointer this ' s not four-byte aligned would crash.
I ' ve run into such crashes before.
But right now I ' ve got a situation where the Release build of an app crashes on an unaligned access,
But the Debug build doesn ' t!
It ' s The exact same place in the code-a CRC32 hash implementation-
And I ' ve verified a odd address is being dereferenced (as a uint32*).
(This was a 32-bit process running on an IPhone 5, by the the-the-the-.)
The only difference are in the assembly code generated.
In the debug build it's using LDR, while in the release build it's using LDRD.
(Apparently the optimizer is a smart enough to realize, the next line of code was loading the next 4 bytes after the Poin ter
So it decides-combine both lines into a single instruction.)
So I ' m guessing that Ldr (a 32-bit load) allows unaligned access,
But Ldrd (64-bit) doesn ' t?
Is there any comprehensive, up-to-date documentation?
I ' ve found an article from 2010* stating that unaligned accesses is supported but is slower because they trigger an OS t Rap (as on PPC);
But it doesn ' t say anything about LDRD.
There's a stackoverflow q&a about a crash with ldrd**, where the answer states this "LDRD needs the address to be 8-by Te aligned ".
But if that's so, then I think the compiler optimization (-ofast level) in my app was incorrect, because the value it ' s de Referencing is a uint32_t*,
So there's no expectation that it ' s 8-byte aligned.
I believe ARM requires 8-byte loads (LDRD, or doubles into the FPU, etc) require 8-byte alignment and would crash otherwise .
4-byte loads don't require alignment but would be slower if the pointer are not 4-byte aligned.
It would not crash though.
Access to double-byte or 4-byte data in arm cannot be implemented directly through a data type cast, and must be done in a single byte:
Use a single-byte assignment, or a function such as memcpy, but in doing so, first determine whether the data is big-endian or small-ended.
Non-aligned data access operations
For load/store operations, if the data access operation is non-aligned, the system defines the following 3 possible results.
The result of execution is unpredictable.
Ignores the low two bits of the word cell address, that is, the word cell that accesses the address _and 0XFFFFFFC, and ignores the lowest bit value of the half-word cell address, which is the half-word unit that accesses the address bit (addr _and 0xffffffe).
Ignores the low two-bit value of the word cell address value, ignoring the value of the lowest bit of the half-word cell address. There is a storage decency to implement this "ignore". In other words, the address value is sent to the storage system intact.
When non-aligned data access occurs, exactly which of the above 3 processing methods is used is specified by each instruction.
ARM Non-aligned data access operations