### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Global variables alignment  (Read 8293 times)

• New Member
• Posts: 19
##### Global variables alignment
« on: February 16, 2015, 01:35:27 am »
I'm wondering how to make certain of global variable alignment in freepascal for win32. Here's some code where each and every variable is aligned to a 16byte boundary:

---------------------------------------------------
program Project1;

{\$APPTYPE GUI}
{\$align 1}

var
b1,b2,b3,b4:byte;
w1,w2,w3,w4:word;
l1,l2,l3,l4:longint;
q1,q2,q3,q4:int64;

begin
b1:=1;b2:=2;b3:=3;b4:=4;
w1:=1;w2:=2;w3:=3;w4:=4;
l1:=1;l2:=2;l3:=3;l4:=4;
q1:=1;q2:=2;q3:=3;q4:=4;

if (longint(@b2)-longint(@b1))=16 then
halt(1);

if (b1+b2+b3+b4+w1+w2+w3+w4+l1+l2+l3+l4+q1+q2+q3+q4)=0 then
halt(1);
end.
---------------------------------------------------

According to the documentation (http://www.freepascal.org/docs-html/prog/progsu171.html) I expected the byte variables to be aligned on 1byte boundaries, word variables to be aligned on 2byte boundaries, and the others on 4byte boundaries. But every single variable is aligned on 16byte boundaries.

Is there a way to control on what boundary global variables are aligned by free pascal?

#### engkin

• Hero Member
• Posts: 3112
##### Re: Global variables alignment
« Reply #1 on: February 16, 2015, 03:48:44 am »
Switch to the external assembler: -Aas
Optimize for size: -Og

On the other hand, odd alignment implies a structured data?
Code: [Select]
`program project1;{\$APPTYPE GUI}{\$ALIGN 1}typeTRec = packed record b1,b2,b3,b4:byte; w1,w2,w3,w4:word; l1,l2,l3,l4:longint; q1,q2,q3,q4:int64;end;var  r: TRec;begin with r do begin b1:=1;b2:=2;b3:=3;b4:=4; w1:=1;w2:=2;w3:=3;w4:=4; l1:=1;l2:=2;l3:=3;l4:=4; q1:=1;q2:=2;q3:=3;q4:=4; if (@b2-@b1)=16 then  halt(1); if (b1+b2+b3+b4+w1+w2+w3+w4+l1+l2+l3+l4+q1+q2+q3+q4)=0 then  halt(1); end;end.`
Notice that \$ALIGN is for records.

• New Member
• Posts: 19
##### Re: Global variables alignment
« Reply #2 on: February 16, 2015, 04:33:36 am »
Yeah i realize that \$align is for record field alignment. However for delphi xe7 (not sure when it was implemented) there's a little documented keyword to choose memory alignment of global variables like so:

type
record_align8=record
a,b,c:longint;
end align 8;

It's not a functionality i'm missing in free pascal if global variables are always aligned on 16byte boundaries, but what I'd like to know is what are the rules of global variable alignment since they seem to differ from what the documentation states, and what are the ways to influence them.

As for optimize for size the documentation page I linked lists what it should give but I didn't try it.
« Last Edit: February 16, 2015, 04:46:16 am by Marladu »

#### engkin

• Hero Member
• Posts: 3112
##### Re: Global variables alignment
« Reply #3 on: February 16, 2015, 05:18:36 am »
However for delphi xe7 (not sure when it was implemented) there's a little documented keyword to choose memory alignment of global variables

like so:

type
record_align8=record
a,b,c:longint;
end align 8;

The example you gave is to declare a type not a variable. Would adding "align 8" align the elements of the record, or global variables of type record_align8?

• New Member
• Posts: 19
##### Re: Global variables alignment
« Reply #4 on: February 16, 2015, 05:49:43 pm »
However for delphi xe7 (not sure when it was implemented) there's a little documented keyword to choose memory alignment of global variables

like so:

type
record_align8=record
a,b,c:longint;
end align 8;

The example you gave is to declare a type not a variable. Would adding "align 8" align the elements of the record, or global variables of type record_align8?

The effect of that keyword is that global variables of that type will be aligned on memory boundaries that are multiples of the specified value. For example:

type
record_align8=record
a,b,c:longint;
end align 8;
record_align16=record
a,b,c:longint;
end align 16;
var
aligned8:record_align8;   // this global variable will be aligned to memory addresses ending in \$0 or \$8 only
aligned16:record_align16; // this global variable will be aligned to memory addresses ending in \$0 only

This won't cause this type if used as a record field to be aligned like with the {\$align} directive though.

As for official documentation I can't seem to find any right now, perhaps it is not documented yet? Dunno how I found out about it then, but I've been using it for a couple months to properly align constants used by SSE code.

But regardless of what delphi does, I'd like to go back to the subject of this thread and find  out what the rules of global variable alignment for win32 are in free pascal since they don't seem to match the documentation listed in the first post. For now it appears to be that all global variables are always aligned to 16byte memory boundaries on win32 target.

edit: here's a link where an example is shown (in the second answer): http://stackoverflow.com/questions/8460862/what-does-packed-now-forces-byte-alignment-of-records-mean . So it seems it's been supported since delphi xe2.
« Last Edit: February 16, 2015, 05:54:46 pm by Marladu »

#### User137

• Hero Member
• Posts: 1791
##### Re: Global variables alignment
« Reply #5 on: February 16, 2015, 09:06:29 pm »
You can still solve all your aligning problems by wrapping them inside records?
Code: [Select]
`{\$ALIGN 1}...TGlobalVarPack1 = record  a, b: byte;  c, d: byte;end; // sizeof 4 bytesvar  gv1: TGlobalVarPack1;implementation...`Any mistakes there, or should it just be packed record?