Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean when my CPU doesn't support unaligned memory access?

I just discovered that the ARM I'm writing code on (Cortex M0), doesn't support unaligned memory access.

Now in my code I use a lot of packed structures, and I never got any warnings or hardfaults, so how can the Cortex access members of these structures when it doesnt allow for unaligned access?

like image 590
Maestro Avatar asked Feb 03 '13 10:02

Maestro


People also ask

What is unaligned memory access?

Unaligned memory accesses occur when you try to read N bytes of data starting from an address that is not evenly divisible by N (i.e. addr % N != 0). For example, reading 4 bytes of data from address 0x10004 is fine, but reading 4 bytes of data from address 0x10005 would be an unaligned memory access.

What is an unaligned address?

An unaligned address is then an address that isn't a multiple of the transfer size. The meaning in AXI4 would be the same.

Does ARM support unaligned access?

ANSWER. By default, ARM7 and ARM9 based microcontrollers do not allow un-aligned accesses to 16-bit and 32-bit data types. Cortex-M3 supports even un-aligned accesses, so the program above would behave correctly.


2 Answers

Compilers such as gcc understand about alignment and will issue the correct instructions to get around alignment issues. If you have a packed structure, you will have told the compiler about it so it know ahead of time how to do alignment.

Let's say you're on a 32 bit architecture but have a struct that is packed like this:

struct foo __attribute__((packed)) {
   unsigned char bar;
   int baz;
}

When an access to baz is made, it will do the memory loads on a 32 bit boundary, and shift all the bits into position.

In this case it will probably to a 32 bit load of the address of bar and a 32 bit load at the address of bar + 4. Then it will apply a sequence of logical operations such as shift and logical or/and to end up with the correct value of baz in a 32 bit register.

Have a look at the assembly output to see how this works. You'll notice that unaligned accesses will be less efficient than aligned accesses on these architectures.

like image 69
Austin Phillips Avatar answered Sep 18 '22 03:09

Austin Phillips


On many older 8-bit microprocessors, there were instructions to load (and storing) registers which were larger than the width of the memory bus. Such an operation would be performed by loading half of the register from one address, and the other half from the next higher address. Even on systems where the memory bus is wider than 8 bits wide (say, 16 bits) it is often useful to regard memory as being an addressable collection of bytes. Loading a byte from any address will cause the processor to read half of a 16-bit memory location and ignore the other half. Reading a 16-bit value from an even address will cause the processor to read an entire 16-bit memory location and use the whole thing; the value will be the same as if one read two consecutive byte addresses and concatenated the result, but it will be read in one operation rather than two.

On some such systems, if one attempts to read a 16-bit value from an odd address, the processor will read two consecutive addresses, using half of one value and the other half of the other value, as though one had performed two single-byte reads and combined the results. This is called an unaligned memory access. On other systems, such an operation will result in a bus fault, which generally triggers some form of interrupt which may or may not be able to do something useful about it. Hardware to support unaligned accesses is rather complicated, and designing code to avoid unaligned accesses is generally not overly difficult. Thus, such hardware generally only exists either on processors that are already very complicated, or processors which will be running code that was designed for processors that would assembly multi-byte registers from single-byte reads (e.g. on the 8088, every 16-bit read required two 8-bit memory fetches, and a lot of 8088 code was run on later Intel processors).

like image 27
supercat Avatar answered Sep 22 '22 03:09

supercat