Что происходит, когда ассемблерный код переводится в код объекта?

Я заинтересован в разработке системного программного обеспечения. Я анализировал работу компилятора в течение нескольких дней. Код сборки, сгенерированный компилятором (скажем) clcимеет код операции f8 и я уверен, что Ассемблер, собирающий вышеуказанную мнемонику, заменяет его код операции f8 на своем месте.

Что беспокоит меня, так это последствия этой стадии (я знаю промежуточную стадию связывания).

Я имею в виду, что именно происходит после этого этапа? Скажем, последний исполняемый файл представляет собой необработанный двоичный файл. Означает ли это код операции f8 преобразуется в двоичные данные 1111 1000 и хранится в файле?

Если это так, то почему я не могу просмотреть двоичное содержимое двоичного файла с помощью обычного текстового редактора (например, "Блокнот") - в конце концов, это "0" и "1" правильно?

1 ответ

Решение

Во-первых, всегда используйте правильный инструмент для работы. Текстовый редактор для просмотра бинарных файлов такой же, как использовать нож для гвоздя. Используйте любой HEX viewer/ редактор для таких задач или лучше используйте инструмент, который знает внутренности рассматриваемого двоичного файла. Если мы говорим о кодах операций процессора, то что-то вроде IDA Pro free или OllyDbg будет полезно для анализа внутренних элементов исполняемых файлов.

Означает ли это код операции f8 преобразуется в двоичные данные 1111 1000 и хранится в файле?

Как правильно указал @Mokubai - 0xF8 тот же номер, что и 1111 1000один представлен в шестнадцатеричном формате, а последний - в двоичном представлении. Это то же самое, что число 248 в десятичной системе.

Если вы создаете исполняемый вручную код из кодов процессора (или компилируете исходный код на ассемблере), то процессор i386 распознает 0xF8 (или же 0b11111000 или 248 - это все так же) как CLC инструкция.

Код сборки, сгенерированный компилятором (скажем) clc имеет код операции f8 и я уверен, что Ассемблер, собирающий вышеуказанную мнемонику, заменяет его код операции f8 на своем месте.

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

В настоящее время мы в основном используем "прямую" компиляцию из языка программирования высокого уровня напрямую в исполняемые двоичные файлы с такими компиляторами, как C/C++/GoLang, которые генерируют коды операций процессора.
(Когда я сказал "прямая компиляция", это на самом деле не так, когда компиляторы под капотом делают несколько шагов, прежде чем он производит исполняемые двоичные файлы, но для конечного пользователя это выглядит так же, как мы за рулем автомобиля без необходимости знать, как бензин превращается в движение)

Как правильно упомянул @sawdust в комментарии, языки программирования более высокого уровня могут использовать разные стратегии для создания кодов операций ЦП. Вы можете проанализировать, например, gcc компилятор, как он будет готовить коды операций, говоря ему генерировать ассемблерный код, который будет использоваться для создания кодов операций (объектные коды)

 gcc -S -o myprogram.asm myprogram.c

Если это так, то почему я не могу просмотреть двоичное содержимое двоичного файла с помощью обычного текстового редактора (например, "Блокнот") - в конце концов, это "0" и "1" правильно?

Блокнот говорят на другом языке. Он понимает свои собственные "коды операций" - ASCII, все остальное, что он "греческий" для Блокнота.

Другие вопросы по тегам