Вызов main()
- это вещь C, в то время как вызов _start()
- вещь ядра, указанная точкой входа в заголовке двоичного формата. (для ясности: ядро не хочет или не должно знать, что мы называем это _start
)
Если бы у вас был бинарный файл, отличный от C, у вас, возможно, не было бы функции main()
, у вас вообще не было бы понятия «функция».
Таким образом, фактический вопрос будет таким: почему компилятор не дает адрес main()
в качестве отправной точки? Это потому, что типичные реализации libc хотят выполнить некоторые инициализации перед тем, как действительно запустить программу, см. Другие ответы для этого.
изменить в качестве примера, вы можете изменить точку входа следующим образом:
$ cat entrypoint.c
int blabla() { printf("Yes it works!\n"); exit(0); }
int main() { printf("not called\n"); }
$ gcc entrypoint.c -e blabla
$ ./a.out
Yes it works!