(这是一个为win32汇编结构体中域的内存对齐的理解)
内存对齐:
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 “内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。
内存对齐的作用:
有些平台每次读都是从偶地址开始,如果一个WORD型数据存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该WORD数据。显然在读取效率上下降很多。
假如我们从内存空间0x01114000处开始划分数据空间,那么:
0x01114000、0x01114001、0x01114002、0x01114003、0x01114004、0x01114005... ...这些地址是在8位(字节)边界上
0x01114000、0x01114002、0x01114004、0x01114006、0x01114008、0x0111400A... ...这些地址是在16位(字)边界上
0x01114000、0x01114004、0x01114008、0x0111400C、0x01114010、0x01114014... ...这些地址是在32位(双字)边界上
0x01114000、0x01114008、0x01114010、0x01114018、0x01114020、0x01114028... ...这些地址是在64位(8字节)边界上
。。。 。。。。
如果我们存储的数据类型为BYTE、SBYTE类型,数据就对齐在“字节”边界上;
如果我们存储的数据类型为WORD、SWORD类型,数据就对齐在”字“边界上;
如果我们存储的数据类型为DWORD、SWORD类型,数据就对齐在“双字”边界上;
如果我们存储的数据类型为QWORD类型,数据就对齐在8字节边界上
这里的例子是使各结构成员根据其数据类型进行对齐(域对齐),否则cpu在访问结构的成员时就要花费更多的时间:
【此处定义了一个Employee的结构,我们可以看SalaryHistory这个结构成员“未对齐”后内存存储状况】
"03处" 的地址是0x01324030,此处也是SalaryHistory成员首地址,从0x01324000--0x01324030相隔2Ah个字节,
2Ah=42,,42%4≠0,42%8≠0,说明“03处”既不在双字边界上,也不在8字节边界上。
【此处定义了一个Employee的结构,我们可以看SalaryHistory这个结构成员“对齐”后内存存储状况】
"03处" 的地址是0x01324036,此处也是SalaryHistory成员首地址,从0x01324000--0x01324030相隔30h个字节,
30h=48,,48%8=0,说明“03处”在8字节边界上,也就是ALIGN伪指令对齐SalaryHistory后的结果。而且
ALIGN伪指令只对齐其后的一个数据。
额外的例子: