Как компилятор "знает", как преобразовать код в специфичную для процессора сборку?
Вещи, которые ответчики уже знают, но здесь в любом случае показать мой мыслительный процесс:
Переходя от HLL к машинному коду, вот примерный набор происходящих событий (есть линкеры и другие вещи, но давайте пока проигнорируем это):
HLL -> Компилятор -> Ассемблер ----> Машинный код
В зависимости от того, какое оборудование я покупаю, он может иметь различный процессор (Intel, SPARC, ARM и т. Д.). А язык ассемблера зависит от процессора. Поэтому, когда код идет из Compiler -> Assembler, генерируемый ассемблерный код зависит от процессора.
Приступая к делу:
Например: у меня ОС Windows на моем оборудовании. И я получаю, скажем, "C компилятор для Windows 7 64bit". У меня также есть Ubuntu на том же оборудовании, и я получаю 'C-компилятор для Ubuntu 64 bit'.
У меня могут быть одинаковые ОС на другом оборудовании с разной архитектурой процессора или разные ОС на одном оборудовании (как в примере выше). Когда я загружаю компилятор C, почему компиляторы указаны как специфичные для ОС? В отличие от процессора? Поскольку весь смысл компилятора состоит в том, чтобы перевести HLL в сборку, которая зависит от архитектуры процессора, а не от конкретной ОС.
Предполагая, что 1. как это делается, и когда я загружаю компилятор для Windows 7 и Ubuntu, как компилятор узнает, какой специфичный для процессора код сборки генерировать? Приходит ли компилятор с различными ассемблерами для конкретного процессора?
2 ответа
Несколько факторов играют в это. Для настольных компьютеров практически используются только две архитектуры: 32-разрядная - x86 (с различными расширениями), 64-разрядная - x86-64. Поэтому многие программы могут просто игнорировать эту проблему и указывать только "битность". Это особенно верно для Windows до Windows RT/8, которая даже не пытается поддерживать какие-либо другие архитектуры.
Хотя компилятор должен знать об архитектуре процессора, практически все интересные программы должны так или иначе взаимодействовать с операционной системой. И даже если ваш код не взаимодействует с ОС, компилятор должен знать, какой формат файла использовать для двоичных файлов, с какими библиотеками связываться и т. Д. Библиотека времени выполнения также зависит от ОС и обычно поставляется вместе с компилятором.
Относительно того, как компилятор знает, какие инструкции генерировать: либо загруженный вами двоичный файл специально приспособлен для одной архитектуры (независимо от того, упоминается ли на этой странице, о которой вы его упомянули), и не может генерировать код для других архитектур, или это действительно так. имеет несколько бэкэндов, скомпилированных в.
Тем не менее, я не вижу много заявленных компиляторов "<language>
компилятор для <operating system>
". Авторы компиляторов, как правило, гораздо более педантичны в определении наборов инструкций, как и дистрибьюторы. Только парни из Windows очень небрежно относятся к этому, потому что примерно год назад это не было полезной информацией".
Для реальных вычислений, таких как добавление двух чисел, важны только аппаратные средства, и вы действительно получите одинаковый машинный код в Windows и Linux.
Интересный "клей" обеспечивается библиотеками платформы, например, стандартной библиотекой C, которая предоставляет функцию "печати символов в стандартном выводе". Код вызова функции также полностью определяется аппаратным обеспечением (хотя существуют некоторые соглашения, которые различаются в Windows и Linux, например, где помещать аргументы функции, но это просто соглашения). Интересное специфичное для платформы "мясо" обеспечивается реализацией этих библиотек. Например, как это printf
реализовано? Разный код генерируется в Linux и Windows, но различия заключаются не в виде инструкций, а в том, как вы общаетесь с операционной системой.
Опять же, это в основном вопрос соглашения, и нет никакого существенного различия в реальном машинном коде программ для разных операционных систем на одном и том же оборудовании. Разница лишь в том, как вы заставляете операционную систему выполнять определенные действия от вашего имени, такие как ввод / вывод, выделение памяти, указание времени и т. Д.