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:
      DIM mystruct{member1, member2, etc, padding%}
      !(^mystruct{}+4) = (mystruct{}+4) AND -8
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:
      DIM mystruct{member1, member2, etc, padding%(2)}
      !(^mystruct{}+4) = (mystruct{}+12) AND -16

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):
      DIM mystruct{member1, member2, etc}
      DIM newdata% DIM(mystruct{})+6
      !(^mystruct{}+4) = (newdata%+7) AND -8
Similarly to align it on a multiple-of-16 address:
      DIM mystruct{member1, member2, etc}
      DIM newdata% DIM(mystruct{})+14
      !(^mystruct{}+4) = (newdata%+15) AND -16
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:
      LOCAL mystruct{}, newdata%
      DIM mystruct{member1, member2, etc}
      DIM newdata% LOCAL DIM(mystruct{})+6
      !(^mystruct{}+4) = (newdata%+7) AND -8