Ваш первый вопрос был дан в руководстве.
Когда вы загружаете программу в операционную систему, ваш раздел .data, в основном ненулевые глобалы, загружается из «двоичного» в правый смещение в памяти для вас, так что когда ваша программа запускает эти ячейки памяти, которые Представьте, что ваши переменные имеют эти значения.
unsigned int x=5;
unsigned int y;
Как программист на языке C вы пишете вышеуказанный код, и вы ожидаете, что x будет 5, когда вы впервые начнете использовать его? Ну, если вы загружаетесь со вспышки, голой металл, у вас нет операционной системы, чтобы скопировать это значение в баран для вас, кто-то должен это сделать. Кроме того, весь материал .data должен быть в состоянии вспышки, номер 5 должен быть где-то во вспышке, чтобы его можно было скопировать в ram. Поэтому для этого вам нужен адрес флэш-памяти и адрес ram. Два адреса для одного и того же.
И это начинает отвечать на ваш второй вопрос. Для каждой строки кода C, которую вы пишете, вы принимаете такие вещи, как, например, любая функция может вызывать любую другую функцию. Вы хотели бы иметь возможность вызывать функции да? И вы хотели бы иметь локальные переменные, и вам нужно, чтобы переменная x выше была равна 5, и вы могли бы предположить, что y будет равно нулю, хотя, к счастью, компиляторы начинают предупреждать об этом. Код запуска как минимум для общего C устанавливает указатель стека, который позволяет вам вызывать другие функции и иметь локальные переменные и имеет функции более одной или двух строк кода, он нули .bss, чтобы переменная y выше равен нулю, и он копирует значение 5 в ram, так что x готов к работе, когда выполняется запуск функции C точки входа C.
Если у вас нет операционной системы, тогда у вас должен быть код, чтобы сделать это, и да, существует много много песочниц и наборов инструментов, которые настроены для различных платформ, у которых уже есть сценарий запуска и компоновщика, чтобы вы могли просто
gcc -O myprog.elf myprog.c
Теперь это не означает, что вы можете сделать системные вызовы без ... система ... Printf, Еореп и т.д. Но если вы загрузите один из этих компилированных инструментов это не означает, что вы не на самом деле нужны написать сценарий компоновщика или загрузчик.
Но по-прежнему ценная информация, обратите внимание, что код запуска и сценарий компоновщика необходимы для программ на базе операционной системы, это только то, что нативные компиляторы для вашей операционной системы предполагают, что вы собираетесь писать программы для этой операционной системы , и в результате они предоставляют сценарий компоновщика и код запуска в этой инструментальной цепочке.