Aligning+structures

//by Richard Russell, June 2010//

BBC BASIC's [|structures] are by default aligned on a **DWORD** boundary, i.e. the memory address of the first member of the structure will always be an exact multiple of four. This is a requirement for some structures passed to Windows API functions.

Rarely, it may be necessary or desirable to use a different alignment, for example you might want the structure to be at an address which is always a multiple of 8 or 16 (for example if the data will be accessed by **MMX** or **SSE** instructions).

There are two main ways of achieving that. The first is to adjust the position of the structure by the smallest amount necessary, and the other is to move the structure's data to a completely new memory location.

Method 1
This involves two steps, firstly adding some dummy //padding// to the end of the structure so that there is room to move its data (if necessary), and secondly to adjust the structure's data address. For example to align a structure on a **QWORD** boundary (a multiple-of-eight address) you can do this: code format="bb4w" DIM mystruct{member1, member2, etc, padding%} !(^mystruct{}+4) = (mystruct{}+4) AND -8 code When the structure is declared, a dummy member **padding%** is added at the very end; this allows the structure to be moved up in memory by 4 bytes, if necessary, without corrupting subsequent memory contents; //it is vitally important that this member is never written//! The second line adjusts the address of the structure so that it is a multiple of eight.

If you want to align the structure at a multiple-of-16 address the padding needs to be 12 bytes in size, most easily arranged by making it an array: code format="bb4w" DIM mystruct{member1, member2, etc, padding%(2)} !(^mystruct{}+4) = (mystruct{}+12) AND -16 code

Method 2
With this method there is no need to add any padding to the structure, but the original structure's storage is wasted so it is less efficient in memory use. To align a structure on a **QWORD** boundary (a multiple-of-eight address): code format="bb4w" DIM mystruct{member1, member2, etc} DIM newdata% DIM(mystruct{})+6 !(^mystruct{}+4) = (newdata%+7) AND -8 code Similarly to align it on a multiple-of-16 address: code format="bb4w" DIM mystruct{member1, member2, etc} DIM newdata% DIM(mystruct{})+14 !(^mystruct{}+4) = (newdata%+15) AND -16 code Note that you must declare the structure using this method **only once** and not repeat the above code (for example in a loop).

If declaring a structure for local use in a procedure or function, use **DIM LOCAL**: code format="bb4w" LOCAL mystruct{}, newdata% DIM mystruct{member1, member2, etc} DIM newdata% LOCAL DIM(mystruct{})+6 !(^mystruct{}+4) = (newdata%+7) AND -8 code