Ответ 1
Операционная система вызывает функцию main()
. На самом деле, он обычно вызывает что-то еще по-другому странное, как _init
. Компилятор C связывает стандартную библиотеку с каждым приложением, которое предоставляет этой операционной системе определенную точку входа, а затем вызывает main()
.
Изменить: Очевидно, что это было недостаточно подробным и правильным для некоторых людей.
Исполняемый и связанный формат (ELF), который используется во многих ОС Unix, определяет адрес точки входа. Именно здесь программа начинает запускаться после завершения OS-вызова exec()
. В системе Linux это _init.
Из objdump -d:
Disassembly of section .init:
08049f08 <_init>:
8049f08: 55 push %ebp
8049f09: 89 e5 mov %esp,%ebp
8049f0b: 83 ec 08 sub $0x8,%esp
8049f0e: e8 a1 05 00 00 call 804a4b4 <call_gmon_start>
8049f13: e8 f8 05 00 00 call 804a510 <frame_dummy>
8049f18: e8 d3 50 00 00 call 804eff0 <__do_global_ctors_aux>
8049f1d: c9 leave
8049f1e: c3 ret
От readelf -d:
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x8049f08
0x0000000d (FINI) 0x804f018
0x00000004 (HASH) 0x8048168
0x00000005 (STRTAB) 0x8048d8c
0x00000006 (SYMTAB) 0x804867c
0x0000000a (STRSZ) 3313 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x8059114
0x00000002 (PLTRELSZ) 688 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x8049c58
0x00000011 (REL) 0x8049be0
0x00000012 (RELSZ) 120 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x8049b60
0x6fffffff (VERNEEDNUM) 3
0x6ffffff0 (VERSYM) 0x8049a7e
0x00000000 (NULL) 0x0
Вы можете видеть, что INIT равен адресу _init.
Код для frame_dummy и __do_global_ctors_aux находится в наборе файлов с именем crtbegin.o и crtend.o(и варианты этих имен). Это часть GCC. Этот код делает различные вещи, необходимые для программы на C, например, для настройки stdin, stdout, глобальных и статических переменных и других вещей.
В следующей статье достаточно хорошо описывается, что она делает в Linux (взято из нижеприведенного ответа с меньшим количеством голосов): http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html
Я считаю, что кто-то еще ответ уже описал, что делает Windows.