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)
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字节的数据。