Это путешествие начинается с того, что наша программа на C только что вышла из текстового редактора. Для этого примера я создал программу с именем 4-puts.c, используя функцию puts() для вывода предложение «Программирование похоже на сборку многоязычной головоломки для стандартного вывода, за которой следует новая строка (\n).

В процессе компиляции есть четыре важных компонента (модуля), я немного объясню, что происходит на каждом из шагов. Чтобы немного лучше понять процесс, я использовал флаг -save-temps, чтобы сохранить временные файлы, используемые в процессе компиляции gcc, в моем текущем каталоге вместе с моим исполняемый файл 4-puts.

Предварительная обработка

На предыдущем шаге мы получили файл 4-puts.i, который является результатом работы нашего компонента предварительной обработки. На этом этапе и внутри наших файлов .i мы найдем задачи, выполняемые препроцессором, который удаляет комментарии из нашего файла, а затем расширяет заголовок файлы в исходный код, чтобы увидеть объявление нашей функции puts(), и третье важное изменение заключается в том, что все макросы расширены. В конце файла мы все равно найдем строчки написанного нами кода.

Компиляция

Когда компонент предварительной обработки завершен, компилятор принимает 4-puts.i в качестве входных данных и создает файл .s, содержащий инструкции уровня сборки (отсюда и название) в качестве выходных данных. внутри нашего файла 4-puts.s. Это инструкции, определенные мнемоникой, которую наш ассемблер может понять, чтобы преобразовать ее позже в язык машинного уровня.

Сборка

Этот следующий компонент принимает в качестве входных данных наш файл 4-puts.s для сборки этих инструкций в код машинного уровня или объектный код в нашем объектном файле .o. В этом компоненте только существующий код преобразуется в машинный язык, но он не читается человеком, EFL в нашей первой строке кода означает исполняемый и компонуемый формат, и это формат для объектных файлов машинного уровня, созданных gcc. Вызовы функций, подобные нашей puts(), еще не разрешены.

Связывание

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

В нашем примере с именем 4-puts. Итак, последнее, что осталось сделать, это запустить нашу программу на C с помощью команды ./4-puts, например:

Наше предложение будет напечатано со специальным символом и добавленным пробелом (\n). На этом наше путешествие по 4 компонентам компиляции gcc подошло к концу.