Прошло почти четыре года с тех пор, как я работал с C. Я хотел вернуться к C и освежить свои основы. Я начал с компиляции C. Это одна из важных концепций, которая всегда очаровывала меня, поскольку она преобразует инструкции, читаемые человеком, в инструкции, понятные машине.

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

Чтобы понять этапы преобразования исходного кода в двоичный формат. мы можем использовать опции компилятора clang для каждого этапа и видеть их вывод.

Я написал простую программу (hello.c) для демонстрации.

#include<stdio.h> 
int main(void){ 
 printf(“Hi there\n”);
}

Любая программа будет проходить следующие 4 этапа компиляции:

  1. Предварительная обработка. На этом этапе все комментарии удаляются, а макросы расширяются. Однако вывод по-прежнему находится в удобочитаемом формате. Выход можно найти здесь
% clang -E hello.c

2. Компиляция. На этом этапе код преобразуется в инструкции по сборке (эти инструкции могут различаться на разных ПК). Выход можно найти здесь

% clang -S hello.c

3. Сборка: на этом этапе мы преобразуем инструкции сборки в двоичный формат. Однако вывод еще не готов к выполнению, поскольку двоичный код для библиотек, связанных в программе, еще не добавлен к выводу. .Вывод можно найти здесь

% clang -c hello.c

4. Связывание: на этом этапе мы получаем полный двоичный вывод, который включает библиотеку, связанную с нашей программой, например ‹stdio.h›.Вывод можно найти "здесь"

% clang -o hello hello.c

После последнего шага мы получаем файл с именем a.out по умолчанию. Но мы можем изменить имя выходного файла, используя опцию -o (clang -o hello hello.c). Это создаст двоичный файл с именем hello, а не загадочный a.out (сокращение от ассемблерного вывода).

Теперь самое интересное. Если вы когда-нибудь попытаетесь открыть двоичный файл или исполняемый файл и увидите мусорные символы/зашифрованные символы, а не o и 1, вы не одиноки.

Причина этих загадочных символов заключается в том, что любые программы, которые мы используем (кошка, блокнот и т. д.), откроют файл, содержащий 0 и 1, и преобразуют их в некоторую кодировку, которую они поддерживают по умолчанию. Следовательно, мы не сможем увидеть фактические 0 и 1.

Чтобы увидеть фактический двоичный код, мы можем использовать такие инструменты, как «xxd», которые доступны в большинстве дистрибутивов Linux/Mac.

i.e % xxd -b <binary file name>   (ex. % xxd -b a.out)

Надеюсь, этот пост поможет!!!

Если у вас есть какие-либо вопросы/дополнения, пожалуйста, не стесняйтесь оставлять комментарии ниже.