Действительно ли скомпилированные программы находятся в истинном двоичном коде?

Например, когда я компилирую приложение C, выводимый файл читается как двоичный файл или ОС интерпретирует компиляцию? Является ли "машинный язык" чисто двоичным?

РЕДАКТИРОВАТЬ: Да, все на компьютере является чисто двоичным. Я спрашиваю, интерпретирует ли процессор напрямую файл, выводимый компилятором, или ОС обрабатывает его первым?

6 ответов

Решение

Скомпилированная программа обычно содержит заголовок, за которым следуют инструкции процессора (то, что вы могли бы назвать "двоичным") + различные другие данные.

Когда вы пытаетесь указать ОС загрузить вашу программу, заголовок будет прочитан ОС, и он используется для проверки того, что исполняемый файл действительно является исполняемым файлом, предназначенным для этой ОС и этой архитектуры. Т.е. чтобы вы случайно не запускали программу Linux на Windows или аналогичную.

Заголовок также содержит различные другие биты информации о том, где фактические инструкции ЦП находятся в исполняемом файле, где расположены сегменты данных (текст, строки, графика) и так далее.

Если ОС довольна тем, что исполняемый файл является тем, чем должен быть, ОС загрузит различные сегменты из исполняемого файла в память и даст указание CPU запустить запуск сегмента "двоичного кода". Этот код "чистый" в том смысле, что он является прямым кодом сборки процессора.

Однако операционная система может прервать ЦП (например, переключиться на другую программу или просто убить программу из памяти и т. Д.). Так что вокруг этой работающей программы происходит много вещей, и ОС вроде бы "управляет" ею и обеспечивает ее поведение как хорошего мальчика, но сам код, когда он выполняется, выполняет чистые инструкции процессора как можно быстрее.... без ОС, которая должна интерпретировать код между ними.

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

Это в двух словах. Есть много других способов запуска программ. Существуют виртуальные машины, интерпретируемые языки (например, Java или Ruby) и так далее. И все они запускают программы по-разному от традиционных "чисто двоичных" языков, таких как C/C++, но, надеюсь, это помогло вам понять, как это работает немного лучше.

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

Однако они являются чисто двоичными. Все на компьютере есть.

РЕДАКТИРОВАТЬ

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

Что вы имеете в виду "настоящий двоичный файл"? Все данные в компьютере равны 1 и 0, хотя ЦП "интерпретирует" коды операций в соответствии с расположением внутренних вентилей и транзисторов. Там нет платонического идеала бинарного языка.

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

Подобные приложения обычно компилируются в машинный код, инструкции выполняются непосредственно процессором:

http://en.wikipedia.org/wiki/Machine_code

x86 ASM является одним из самых распространенных. Думайте об этом как о том, что ваш код компилируется в язык очень низкого уровня. Это слой выше 1 и 0, отправляемый прямо по металлу, если вы это имеете в виду, и ОС по-прежнему контролирует то, что выполняется. Но да, в конце концов все сводится к бинарному - все на ПК будет делать!

Интересно, почему никто не упомянул концепцию компоновщика.

По сути, выходные данные компилятора на самом деле представляют собой двоичный файл, но здесь есть одна загвоздка. Этот скомпилированный двоичный файл часто называют объектным файлом, который содержит код объекта. Теперь не путайте себя здесь. Код объекта - это не что иное, как машинный код или двоичный код, как вы его называете, но только его часть. Компилятор обычно выводит несколько таких объектных файлов из источника одной программы. По сути, каждый из этих объектных файлов содержит часть полного исполняемого машинного кода для этой программы. Вот где приходит компоновщик. Он в основном связывает все эти объектные файлы в полный исполняемый файл, который машина может запускать как программу.

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