Прошло почти четыре года с тех пор, как я работал с C. Я хотел вернуться к C и освежить свои основы. Я начал с компиляции C. Это одна из важных концепций, которая всегда очаровывала меня, поскольку она преобразует инструкции, читаемые человеком, в инструкции, понятные машине.
В C мы делаем это через компиляцию. Есть четыре шага, необходимые для преобразования письменной инструкции человека в двоичную (язык, используемый машинами).
Чтобы понять этапы преобразования исходного кода в двоичный формат. мы можем использовать опции компилятора clang для каждого этапа и видеть их вывод.
Я написал простую программу (hello.c) для демонстрации.
#include<stdio.h> int main(void){ printf(“Hi there\n”); }
Любая программа будет проходить следующие 4 этапа компиляции:
- Предварительная обработка. На этом этапе все комментарии удаляются, а макросы расширяются. Однако вывод по-прежнему находится в удобочитаемом формате. Выход можно найти здесь
% 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)
Надеюсь, этот пост поможет!!!
Если у вас есть какие-либо вопросы/дополнения, пожалуйста, не стесняйтесь оставлять комментарии ниже.