Linux下C程序执行时,main函数如何被调用
默认情况下,linux下 C程序总是从main函数开始执行。但是main函数是怎么被调用的呢?我们先把结论放在这里。
程序加载以后,_start()是第一个被调用执行的函数。
_start()函数准备好参数以后立即调用 _lib_start_main()函数。
_lib_start_main()初始化运行环境后才调用main()函数执行。
下面以hello.c来逐步剖析main函数被调用的秘密。
int main()
{
printf("hello world!\n");
exit(0);
}
在linux下编译生成hello文件。使用objdump -S 反汇编目标文件hello中的信息。
hello: file format elf32-i386
Disassembly of section .init:
080482b0 <_init>:
80482b0: 55 push %ebp
80482b1: 89 e5 mov %esp,%ebp
80482b3: 53 push %ebx
80482b4: 83 ec 04 sub $0x4,%esp
80482b7: e8 00 00 00 00 call 80482bc <_init+0xc>
80482bc: 5b pop %ebx
80482bd: 81 c3 38 1d 00 00 add $0x1d38,%ebx
80482c3: 8b 93 fc ff ff ff mov -0x4(%ebx),%edx
80482c9: 85 d2 test %edx,%edx
80482cb: 74 05 je 80482d2 <_init+0x22>
80482cd: e8 1e 00 00 00 call 80482f0 <__gmon_start__@plt>
80482d2: e8 e9 00 00 00 call 80483c0 <frame_dummy>
80482d7: e8 a4 01 00 00 call 8048480 <__do_global_ctors_aux>
80482dc: 58 pop %eax
80482dd: 5b pop %ebx
80482de: c9 leave
80482df: c3 ret
Disassembly of section .plt:
080482e0 <__gmon_start__@plt-0x10>:
80482e0: ff 35 f8 9f 04 08 pushl 0x8049ff8
80482e6: ff 25 fc 9f 04 08 jmp *0x8049ffc
80482ec: 00 00 add %al,(%eax)
...
080482f0 <__gmon_start__@plt>:
80482f0: ff 25 00 a0 04 08 jmp *0x804a000
80482f6: 68 00 00 00 00 push $0x0
80482fb: e9 e0 ff ff ff jmp 80482e0 <_init+0x30>
08048300 <__libc_start_main@plt>:
8048300: ff 25 04 a0 04 08 jmp *0x804a004
8048306: 68 08 00 00 00 push $0x8
804830b: e9 d0 ff ff ff jmp 80482e0 <_init+0x30>
08048310 <puts@plt>:
8048310: ff 25 08 a0 04 08 jmp *0x804a008
8048316: 68 10 00 00 00 push $0x10
804831b: e9 c0 ff ff ff jmp 80482e0 <_init+0x30>
08048320 <exit@plt>:
8048320: ff 25 0c a0 04 08 jmp *0x804a00c
8048326: 68 18 00 00 00 push $0x18
804832b: e9 b0 ff ff ff jmp 80482e0 <_init+0x30>
Disassembly of section .text:
08048330 <_start>:
8048330: 31 ed xor %ebp,%ebp
8048332: 5e pop %esi
8048333: 89 e1 mov %esp,%ecx
8048335: 83 e4 f0 and $0xfffffff0,%esp
80