Компиляция языка высокого уровня в машинный код

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

Но это было найдено в одном из моих лекций, поэтому я могу быть признателен, если кто-то сможет объяснить дальше и исправить меня, если я ошибаюсь, или снимок экрана ниже.

Slide

Ответ 1

Ваш слайд в основном неправильный...

Существует сопоставление 1-к-1 между сборкой и машинным кодом. Сборка представляет собой текстовое представление информации, а машинный код - двоичное представление.

Однако некоторые машины поддерживают дополнительные инструкции по сборке, но какие инструкции включены в полученный код сборки, по-прежнему определяются во время компиляции, а не во время выполнения. Вообще говоря, это определяется процессором в системе (intel, amd, ti, nvidia и т.д.), А не производителем, из которого вы покупаете всю систему.

Ответ 2

Этот слайд запутывает байт-код с текстовой сборкой. Сборка - это читаемая пользователем версия либо байт-кода, либо машинного кода. Машинный код - это то, что аппаратное обеспечение может запускать напрямую. Байткод далее компилируется в машинный код, это низкий уровень, но общий.

В некоторых языках используется байт-код, который транслируется во время выполнения на машинный код более низкого уровня. Одним из примеров этого является java, где файлы классов иногда компилируются в машинный код в качестве оптимизации времени выполнения. Другим является cuda, где каждый nvidia gpu имеет другой набор команд, но компилятор cuda генерирует байт-код, который затем может преобразовать драйвер cuda для каждого gpu.

Другим вариантом является то, что он говорит о том, как процессоры Intel преобразуют машинный код во время выполнения во внутренний микрокод, а затем запускают его, но это совершенно незаметно для программного обеспечения, включая ОС.

Ответ 3

Слайд сильно ошибочен во многих отношениях.

Очень упрощенная версия того, что на самом деле происходит в примере, приведенном в слайд-компиляции С++, объясняет, что для создания и выполнения исполняемого файла из файла исходного кода существует четыре этапа:

  • Препроцессирование
  • Компиляция "правильная"
  • Сборка
  • Связь

В фазе preprocessing препроцессорные директивы, такие как #include и #define, полностью расширяются, а комментарии пресекаются препроцессором, создавая "постпроцессированный" С++. Этот слайд полностью исключает.

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

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

В фазе сборки операторы языка ассемблера из предыдущей фазы преобразуются в объектный код (инструкции двоичного машинного кода, которые понимает ЦП, в сочетании с метаданными, которые понимают ОС и компоновщик) ассемблер.

В фазе привязки объектный код из предыдущей фазы связан с другими файлами объектных кодов и общими/системными библиотеками для формирования исполняемого файла.

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

Еще одна ошибка заключается в том, что разные марки машин не имеют своих "собственных машинных кодов". Что определяет, какие машинные коды понимаются машиной, является CPU. Если две машины имеют один и тот же процессор (например, ноутбук Dell и ноутбук Toshiba с тем же процессором Intel i7-3610QM), тогда они понимают одинаковые машинные коды. Более того, два процессора с одной и той же ISA (архитектура набора команд) понимают одни и те же машинные коды. Кроме того, более новые процессоры обычно совместимы с предыдущими процессорами в той же серии. Например, новый процессор Intel i7 понимает все инструкции, которые понимает более старый Intel Pentium 4, но не наоборот.

Надеюсь, я ударил несколько лучшего баланса между простотой и правильностью, чем слайд, выше, который терпит неудачу.