学习C++反汇编-内存对齐

C++源代码:

#include<stdio.h>
struct myStruct
{
	int a;
	char b;
	float c;
};

int main()
{
	myStruct test;
	test.a=0;
	test.b='a';
	test.c=1.0f;
	return 0;
}

生成的汇编代码:

Dump of assembler code for function main:
0x004012f0 <main+0>:	push   %ebp
0x004012f1 <main+1>:	mov    %esp,%ebp
0x004012f3 <main+3>:	sub    $0x28,%esp
0x004012f6 <main+6>:	and    $0xfffffff0,%esp
0x004012f9 <main+9>:	mov    $0x0,%eax
0x004012fe <main+14>:	add    $0xf,%eax
0x00401301 <main+17>:	add    $0xf,%eax
0x00401304 <main+20>:	shr    $0x4,%eax
0x00401307 <main+23>:	shl    $0x4,%eax
0x0040130a <main+26>:	mov    %eax,-0x1c(%ebp)
0x0040130d <main+29>:	mov    -0x1c(%ebp),%eax
0x00401310 <main+32>:	call   0x401844 <_alloca>
0x00401315 <main+37>:	call   0x4013c4 <__main>
0x0040131a <main+42>:	movl   $0x0,-0x18(%ebp)
0x00401321 <main+49>:	movb   $0x61,-0x14(%ebp)
0x00401325 <main+53>:	mov    $0x3f800000,%eax
0x0040132a <main+58>:	mov    %eax,-0x10(%ebp)
0x0040132d <main+61>:	mov    $0x0,%eax
0x00401332 <main+66>:	leave  
0x00401333 <main+67>:	ret    
End of assembler dump.
(gdb) 
0x61转化成十进制是97,也就是a对应的ASCII码。如果我们用sizeof运算符计算一下这个结构体的大小发现它占了12个字节,而理论上char,int,float各占1,4,4个字节,加起来应该占9个字节,造成不一样的原因叫做内存对齐。

每个特定平台上的编译器都有自己的默认对齐系数。程序员可以通过预编译命令#pragmapack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的对齐系数。

规则:

1、数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。

2、整体对齐规则:在数据成员完成各自对齐之后,整体本身也要进行对齐,对齐将按照#pragma pack指定的数值和最大数据成员长度中,比较小的那个进行。

3、结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。


你可能感兴趣的:(学习C++反汇编-内存对齐)