Natural Alignment

Most modern RISC machines mandate that memory accesses are naturally aligned: The address at which an elementary datum is stored must be divisible by the width of the data type. Consider, for instance, a pointer that is 8 bytes wide on 64-bit architectures. Consequently these pointers must be stored at addresses that are divisible by 8, so 24, 32, 800, and so on are valid addresses, whereas 30 and 25 are not. This is not a problem for all ''regular'' operations because when memory is allocated in the kernel, it will be allocated properly. The compiler additionally ensures that structures are padded to enforce natural alignment, but if memory access on arbitrary, non-aligned locations is required, the following two auxiliary functions must be employed:

□ get_unaligned(ptr), which allows for reading an unaligned pointer.

□ put_unaligned(val, ptr), which writes val to the unaligned memory location denoted by ptr.

Older architectures such as IA-32 handle unaligned access transparently, but most RISC machines do not, so the functions must be used on all unaligned accesses to ensure portability.

Consider the following structure:

struct align {

On 64-bit systems, a pointer requires 8 bytes, while a char variable needs 1 byte. Although only 17 bytes are stored in the structure, the size of this definition as reported by sizeof will be 24. This is because the compiler ensures that the second pointer, ptr2, is correctly aligned by placing 7 fill bytes — which are unused — after c. This is illustrated in Figure C-4.

0 ptrl 7 c 8 Padding 15 ptr2 23 Figure C-4: The compiler automatically inserts padding space into structures to make them fulfill alignment requirements.

The padded bytes in the structure lend themselves naturally to be filled with useful information, so you should try to arrange your structures accordingly.

If padding must be avoided because, for instance, a data structure is employed to exchange data with a peripheral device that must receive a data structure exactly as it was defined, the attribute_packed can be specified in the structure definition to prevent the compiler from introducing pad bytes. Naturally, the possibly unaligned components of this structure must then be accessed using the aforementioned functions.

Bytes are always aligned by definition — their width is 1 byte, and every address is divisible by one.

Continue reading here: C24 Bit Arithmetic

Was this article helpful?

0 0