学习C++反汇编-数组初始化

C++源代码:

#include<stdio.h>

int main()
{
	char Hello1[20]={"Hello world"};
	char Hello2[20]={"HelloWorld"};
	return 0;
}

生成的汇编代码:

Dump of assembler code for function main:
0x004012f0 <main+0>:	push   %ebp
0x004012f1 <main+1>:	mov    %esp,%ebp
0x004012f3 <main+3>:	push   %edi
0x004012f4 <main+4>:	sub    $0x54,%esp
0x004012f7 <main+7>:	and    $0xfffffff0,%esp
0x004012fa <main+10>:	mov    $0x0,%eax
0x004012ff <main+15>:	add    $0xf,%eax
0x00401302 <main+18>:	add    $0xf,%eax
0x00401305 <main+21>:	shr    $0x4,%eax
0x00401308 <main+24>:	shl    $0x4,%eax
0x0040130b <main+27>:	mov    %eax,-0x4c(%ebp)
0x0040130e <main+30>:	mov    -0x4c(%ebp),%eax
0x00401311 <main+33>:	call   0x401890 <_alloca>
0x00401316 <main+38>:	call   0x401410 <__main>
0x0040131b <main+43>:	mov    0x403000,%eax
0x00401320 <main+48>:	mov    %eax,-0x28(%ebp)
0x00401323 <main+51>:	mov    0x403004,%eax
0x00401328 <main+56>:	mov    %eax,-0x24(%ebp)
0x0040132b <main+59>:	mov    0x403008,%eax
0x00401330 <main+64>:	mov    %eax,-0x20(%ebp)
0x00401333 <main+67>:	movl   $0x0,-0x1c(%ebp)
0x0040133a <main+74>:	movl   $0x0,-0x18(%ebp)
0x00401341 <main+81>:	mov    0x403014,%eax
0x00401346 <main+86>:	mov    %eax,-0x48(%ebp)
0x00401349 <main+89>:	mov    0x403018,%eax
0x0040134e <main+94>:	mov    %eax,-0x44(%ebp)
0x00401351 <main+97>:	movzwl 0x40301c,%eax
0x00401358 <main+104>:	mov    %ax,-0x40(%ebp)
0x0040135c <main+108>:	movzbl 0x40301e,%eax
0x00401363 <main+115>:	mov    %al,-0x3e(%ebp)
0x00401366 <main+118>:	lea    -0x3d(%ebp),%edi
0x00401369 <main+121>:	cld    
0x0040136a <main+122>:	mov    $0x9,%ecx
0x0040136f <main+127>:	mov    $0x0,%al
0x00401371 <main+129>:	rep stos %al,%es:(%edi)
0x00401373 <main+131>:	mov    $0x0,%eax
0x00401378 <main+136>:	mov    -0x4(%ebp),%edi
0x0040137b <main+139>:	leave  
0x0040137c <main+140>:	ret    
End of assembler dump.
(gdb) 

先研究Hello1的初始化过程:

0x0040131b <main+43>:	mov    0x403000,%eax
0x00401320 <main+48>:	mov    %eax,-0x28(%ebp)
0x00401323 <main+51>:	mov    0x403004,%eax
0x00401328 <main+56>:	mov    %eax,-0x24(%ebp)
0x0040132b <main+59>:	mov    0x403008,%eax
0x00401330 <main+64>:	mov    %eax,-0x20(%ebp)
0x00401333 <main+67>:	movl   $0x0,-0x1c(%ebp)
0x0040133a <main+74>:	movl   $0x0,-0x18(%ebp)
初始化时每次复制4个字节的数据,因为一个寄存器一次可以保存4字节的数据,如果以单字节的方式复制就会浪费掉3字节的空间,而且多次数据传递也会降低执行的效率。将常量字符串分成3段以后依次复制,然后剩余的填充为0。

再来看Hello2的初始化过程:

0x00401341 <main+81>:	mov    0x403014,%eax
0x00401346 <main+86>:	mov    %eax,-0x48(%ebp)
0x00401349 <main+89>:	mov    0x403018,%eax
0x0040134e <main+94>:	mov    %eax,-0x44(%ebp)
0x00401351 <main+97>:	movzwl 0x40301c,%eax
0x00401358 <main+104>:	mov    %ax,-0x40(%ebp)
0x0040135c <main+108>:	movzbl 0x40301e,%eax
0x00401363 <main+115>:	mov    %al,-0x3e(%ebp)
0x00401366 <main+118>:	lea    -0x3d(%ebp),%edi
0x00401369 <main+121>:	cld    
0x0040136a <main+122>:	mov    $0x9,%ecx
0x0040136f <main+127>:	mov    $0x0,%al
0x00401371 <main+129>:	rep stos %al,%es:(%edi)
字符串的前8字节数据的复制过程没有任何变化,最后3字节的字符数据被拆分成两部分,先复制2字节的数据再复制1字节的数据。


你可能感兴趣的:(学习C++反汇编-数组初始化)