Forum > Windows
Global variables alignment
Marladu:
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:
Switch to the external assembler: -Aas
Optimize for size: -Og
On the other hand, odd alignment implies a structured data?
--- Code: ---program project1;
{$APPTYPE GUI}
{$ALIGN 1}
type
TRec = 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.
--- End code ---
Notice that $ALIGN is for records.
Marladu:
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.
engkin:
--- Quote from: Marladu on February 16, 2015, 04:33: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
--- End quote ---
Any link to its documentation?
--- Quote from: Marladu on February 16, 2015, 04:33:36 am ---like so:
type
record_align8=record
a,b,c:longint;
end align 8;
--- End quote ---
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?
Marladu:
--- Quote from: engkin on February 16, 2015, 05:18:36 am ---
--- Quote from: Marladu on February 16, 2015, 04:33: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
--- End quote ---
Any link to its documentation?
--- Quote from: Marladu on February 16, 2015, 04:33:36 am ---like so:
type
record_align8=record
a,b,c:longint;
end align 8;
--- End quote ---
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?
--- End quote ---
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.
Navigation
[0] Message Index
[#] Next page