1

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

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

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

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

1 ответ1

2

Во-первых, всегда используйте правильный инструмент для работы. Текстовый редактор для просмотра бинарных файлов такой же, как использовать нож для гвоздя. Используйте любой 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, все остальное, что он "греческий" для Блокнота.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .