Подтвердить что ты не робот

Что такое _start() в C?

Я узнал от своего коллеги, что можно писать и выполнять программу на C без написания функции main(). Это можно сделать как под

withoutMain.c

// Compile it with gcc -nostartfiles

void _start() {
  int ret = my_main();
  exit(ret); 
}

int my_main() {
  puts("This is a program without main!\n");
  return 0; 
}

Скомпилируйте его как: gcc -o withoutMain withoutMain.c –nostartfiles

Запустите его как: ./ withoutMain

Мой вопрос: когда нужно будет делать такие вещи? Какой-то реальный сценарий?

4b9b3361

Ответ 1

Символ _start - это точка входа вашей программы. То есть, адрес этого символа - это адрес, с которым он перешел в начало программы. Обычно функция с именем _start предоставляется файлом с именем crt0.o, который содержит код запуска среды выполнения C. Он создает некоторые вещи, заполняет массив аргументов argv, подсчитывает, сколько аргументов есть, а затем вызывает main. После возврата main вызывается exit.

Если программа не хочет использовать среду выполнения C, ей необходимо предоставить свой собственный код для _start. Например, эталонная реализация языка программирования Go делает это потому, что им нужна нестандартная модель потоковой передачи, которая требует некоторой магии со стеком. Он также полезен для предоставления собственных _start, когда вы хотите писать действительно крошечные программы или программы, которые делают нетрадиционные вещи.

Ответ 2

Хотя main является точкой входа для вашей программы с точки зрения программистов, _start является обычной точкой входа с точки зрения ОС (первая инструкция, которая запускается после запуска вашей программы из ОС)

В типичной программе C и особенно С++ большая работа была выполнена до того, как выполнение вступит в основное. Особенно такие вещи, как инициализация глобальных переменных. Здесь вы можете найти хорошее объяснение всего, что происходит между _start() и main(), а также после того, как main снова вышел (см. комментарий ниже).
Необходимый код для этого обычно предоставляется авторами компилятора в файле автозагрузки, но с флагом –nostartfiles вы по существу говорите компилятору: "Не утруждайте себя предоставлением стандартного файла запуска, дайте мне полный контроль над тем, что происходит с самого начала".

Это иногда необходимо и часто используется для встроенных систем. Например. если у вас нет ОС, и вы должны вручную включить определенные части вашей системы памяти (например, кеши) до инициализации ваших глобальных объектов.