машинный код и байт код отличие

Путь к пониманию байт-кода V8

V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

машинный код и байт код отличие. 04ac08c9e48756beb3c9742485f0e6ea. машинный код и байт код отличие фото. машинный код и байт код отличие-04ac08c9e48756beb3c9742485f0e6ea. картинка машинный код и байт код отличие. картинка 04ac08c9e48756beb3c9742485f0e6ea. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

Конвейер компиляции V8

машинный код и байт код отличие. image loader. машинный код и байт код отличие фото. машинный код и байт код отличие-image loader. картинка машинный код и байт код отличие. картинка image loader. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

Зажигание! Пуск! Интерпретатор Ignition, название которого можно перевести как «зажигание», является частью конвейера компиляции V8 с 2016-го года

Когда V8 компилирует JavaScript-код, парсер генерирует абстрактное синтаксическое дерево. Синтаксическое дерево — это древовидное представление синтаксической структуры JS-кода. Интерпретатор Ignition генерирует байт-код из этой структуры данных. Оптимизирующий компилятор TurboFan, в итоге, генерирует из байт-кода оптимизированный машинный код.

машинный код и байт код отличие. image loader. машинный код и байт код отличие фото. машинный код и байт код отличие-image loader. картинка машинный код и байт код отличие. картинка image loader. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

Конвейер компиляции V8

Если вы хотите узнать о том, почему V8 имеет два режима исполнения, взгляните на моё выступление с JSConfEU.

Основы байт-кода V8

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

Интерпретатор Ignition — это регистровая машина с накопительным регистром.

машинный код и байт код отличие. image loader. машинный код и байт код отличие фото. машинный код и байт код отличие-image loader. картинка машинный код и байт код отличие. картинка image loader. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

Код слева удобен для людей. Код справа — для машин

Анализ байт-кода функции

Теперь, после того, как мы разобрали основные понятия, посмотрим на байт-код реальной функции.

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

Команда LdaSmi [1] загружает константу 1 в накопительный регистр.

машинный код и байт код отличие. image loader. машинный код и байт код отличие фото. машинный код и байт код отличие-image loader. картинка машинный код и байт код отличие. картинка image loader. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

машинный код и байт код отличие. image loader. машинный код и байт код отличие фото. машинный код и байт код отличие-image loader. картинка машинный код и байт код отличие. картинка image loader. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

LdaNamedProperty a0, [0], [4]

Теперь содержимое регистров выглядит следующим образом.

машинный код и байт код отличие. image loader. машинный код и байт код отличие фото. машинный код и байт код отличие-image loader. картинка машинный код и байт код отличие. картинка image loader. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

машинный код и байт код отличие. image loader. машинный код и байт код отличие фото. машинный код и байт код отличие-image loader. картинка машинный код и байт код отличие. картинка image loader. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

Обратите внимание на то, что байт-код, которому посвящён этот материал, используется в V8 версии 6.2, в Chrome 62 и в ещё не выпущенном Node 9. Мы, в Google, постоянно работаем над V8 в направлениях улучшения производительности и уменьшения потребления памяти. В других версиях V8 в байт-коде могут присутствовать некоторые отличия от того, что было описано здесь.

Итоги

На первый взгляд байт-код V8 может показаться довольно-таки загадочным, особенно когда он выводится с массой дополнительных сведений. Однако, как только вы узнаете о том, что Ignition — это регистровая машина с накопительным регистром, вы сможете понять назначение большинства байт-кодов.

Уважаемые читатели! Планируете ли вы анализировать байт-код ваших JS-программ?

Источник

Разница между двоичным и байт кодом?

машинный код и байт код отличие. tnkWO. машинный код и байт код отличие фото. машинный код и байт код отличие-tnkWO. картинка машинный код и байт код отличие. картинка tnkWO. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

2 ответа 2

Небольшая историческая справка.

В самых первых компьютерах (1940-е годы) команды и данные хранились раздельно. Данные располагались в памяти, а команды задавались перемычками на лицевой панели. Из-за этого некоторые команды нельзя было реализовать в принципе. Например, нельзя было передать управление на команду, адрес которой хранится в памяти. Сейчас с помощью таких косвенных вызовов работают виртуальные методы в Java/C++/C#.

Группа инженеров под руководством Фон Неймана предложила несколько архитектурных принципов, которые помогли сделать компьютеры проще и в то же время мощнее. Один из них гласит, что и программы и данные хранятся в оперативной памяти. Поскольку компьютер не хранит ничего кроме чисел, процессор «видит» программу именно как массив чисел.

Числа хранятся в двоичном виде (ещё один принцип Фон Неймана). Минимальной единицей хранения является байт. Я читал, что существовали компьютеры с 7-битными и 9-битными словами, правда, никогда с ними не работал. Насколько я знаю, уже в конце 60-х годов победил 8-битный байт.

Вот пример машинного кода и его представления на языке Ассемблера. Я нашёл его в Google. Слева указан порядковый номер (адрес) первого байта команды. Во второй колонке мы видим байты команды, они записаны в восьмеричной системе счисления. В третьей колонке мнемоники Ассемблера, которые упрощают восприятие программы человеком. Некоторые команды занимают один байт, а некоторые два. В этом примере нет команд, которые занимают три, четыре и больше байт, но такие команды также встречаются.

Именно это и есть двоичный код, который «понимает» процессор.

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

Если мы захотим написать для них программу, нам придётся писать две программы. Традиционно проблема переносимости решается с помощью языков высокого уровня и компиляторов. Хороший компилятор это сложная программа, которую долго разрабатывать и трудно поддерживать. Если наш компилятор поддерживает пять разных архитектур, в нём пять разных оптимизаторов и кодогенераторов.

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

Виртуальный процессор работает также, как и реальный: он видит массив чисел, и воспринимает их как команды для выполнения. Байт-код внешне совершенно идентичен двоичному коду. Вот пример байт-кода виртуальной машины Java:

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

Источник

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

Машинный код

Машинный код или машинный язык представляет собой набор инструкций, выполняемых непосредственно центральным процессором компьютера (CPU). Каждая команда выполняет очень конкретную задачу, например, загрузки (load), перехода (jump) или элементарной арифметической или логической операции для единицы данных в регистре процессора или памяти. Каждая программа выполняется непосредственно процессором и состоит из ряда таких инструкций.

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

Почти все практические программы сегодня написаны на языках более высокого уровня или ассемблере. Исходный код затем транслируется в исполняемый машинный код с помощью таких утилит, как интерпретаторы, компиляторы, ассемблеры, и/или линкеры. [Источник 1]

Содержание

Инструкции машинного кода (ISA)

Каждый процессор или семейство процессоров имеет свой собственный набор инструкций машинного кода. Инструкции являются паттернами битов, которые в силу физического устройства соответствуют различным командам машины. Говорят, что процессор A совместим с процессором B, если процессор A полностью «понимает» машинный код процессора B. Если процессоры A и B имеют некоторое подмножество инструкций, по которым они взаимно совместимы, то говорят, что они одной архитектуры. Таким образом, набор команд является специфическим для одного класса процессоров. Новые процессоры одной архитектуры часто включают в себя все инструкции предшественника и могут включать дополнительные. Иногда новые процессоры прекращают поддержку или изменяют значение какого-либо кода команды (как правило, потому, что это необходимо для новых целей), влияя на совместимость кода до некоторой степени; даже почти полностью совместимые процессоры могут показать различное поведение для некоторых команд, но это редко является проблемой.

Системы также могут отличаться в других деталях, таких как расположение памяти, операционные системы или периферийные устройства. Поскольку программа обычно зависит от таких факторов, различные системы, как правило, не запустят один и тот же машинный код, даже если используется тот же тип процессора. [Источник 2]

Виды ISA

x86 всегда был архитектурой с инструкциями переменной длины, так что когда пришла 64-битная эра, расширения x64 не очень сильно повлияли на ISA. ARM это RISC-процессор разработанный с учетом инструкций одинаковой длины, что было некоторым преимуществом в прошлом. Так что в самом начале все инструкции ARM кодировались 4-мя байтами. Это то, что сейчас называется «режим ARM».

На самом деле, самые используемые инструкции процессора на практике могут быть закодированы c использованием меньшего количества информации. Так что была добавлена ISA с названием Thumb, где каждая инструкция кодируется всего лишь 2-мя байтами. Теперь это называется «режим Thumb». Но не все инструкции ARM могут быть закодированы в двух байтах, так что набор инструкций Thumb ограниченный. Код, скомпилированный для режима ARM и Thumb может сосуществовать в одной программе. Затем создатели ARM решили, что Thumb можно расширить: так появился Thumb-2 (в ARMv7). Thumb-2 это всё ещё двухбайтные инструкции, но некоторые новые инструкции имеют длину 4 байта. Распространено заблуждение, что Thumb-2 — это смесь ARM и Thumb. Это неверно. Режим Thumb-2 был дополнен до более полной поддержки возможностей процессора и теперь может легко конкурировать с режимом ARM. Основное количество приложений для iPod/iPhone/iPad скомпилировано для набора инструкций Thumb-2, потому что Xcode делает так по умолчанию. Потом появился 64-битный ARM. Это ISA снова с 4-байтными инструкциями, без дополнительного режима Thumb. Но 64-битные требования повлияли на ISA, так что теперь у нас 3 набора инструкций ARM: режим ARM, режим Thumb (включая Thumb-2) и ARM64. Эти наборы инструкций частично пересекаются, но можно сказать, это скорее разные наборы, нежели вариации одного. Существует ещё много RISC ISA с инструкциями фиксированной 32-битной длины — это как минимум MIPS, PowerPC и Alpha AXP. [Источник 3]

Выполнение инструкций

Компьютерная программа представляет собой последовательность команд, которые выполняются процессором. В то время как простые процессоры выполняют инструкции один за другим, суперскалярные процессоры способны выполнять несколько команд одновременно.

Программа может содержать специальные инструкций, которые передают выполнение инструкции, не идущей по порядку вслед за предыдущей. Условные переходы принимаются (выполнение продолжается по другому адресу) или нет (выполнение продолжается на следующей инструкции) в зависимости от некоторых условий.

Абсолютный и позиционно-независимый код

Позиционно-независимый код — программа, которая может быть размещена в любой области памяти, так как все ссылки на ячейки памяти в ней относительные (например, относительно счётчика команд). Такую программу можно переместить в другую область памяти в любой момент, в отличие от перемещаемой программы, которая хотя и может быть загружена в любую область памяти, но после загрузки должна оставаться на том же месте.

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

Хранение в памяти

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

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

Связь с языками программирования

Ассемблерные языки

Гораздо более читаемым представлением машинного языка называется язык ассемблера, использующий мнемонические коды для обозначения инструкций машинного кода, а не с помощью числовых значений. Например, на процессоре Zilog Z80, машинный код 00000101, который дает указание процессору декрементировать регистр процессора B, будет представлен на языке ассемблера как DEC B.

Связь с микрокодом

В некоторых компьютерных архитектурах, машинный код реализуется с помощью более фундаментального базового слоя программ, называемых микропрограммами, обеспечивающими общий интерфейс машинного языка для линейки различных моделей компьютеров с самыми различными базовыми потоками данных. Это делается для облегчения портирования программ на машинном языке между различными моделями. Примером такого использования являются компьютеры IBM System/360 и их наследники. Несмотря на то, что ширина потоков данных разнится от 8 до 64 бит и более, тем не менее они представляют общую архитектуру на уровне машинного языка по всей линейке.

Использование микрокода для реализации эмулятора позволяет компьютеру симулировать совершенно другую архитектуру. Семейство System / 360 использовало это для портирования программ с более ранних машин IBM на новые семейства компьютеров, например на IBM 1401/1440/1460.

Связь с байткодом

Машинный код, как правило, отличается от байт-кода (также известного как р-код), который либо выполняется интерпретатором, или сам компилируется в машинный код для более быстрого исполнения. Исключением является ситуация, когда процессор предназначен для использования конкретного байт-кода как машинного, например, как в случае с процессорами Java. Машинный и ассемблерный код иногда называют собственным (внутренним) кодом ЭВМ, когда ссылаются на платформо-зависимые части свойств или библиотек языка. [Источник 4]

Примеры

Пример MIPS 32-bit инструкции

Набор инструкций MIPS – пример машинного кода с инструкциями фиксированной длины – 32 бита. Тип инструкции содержится в поле op (поле операции) – первые 6 бит. Например типы инструкций перехода или немедленных операций полностью определяются этим полем. Инструкции регистров включают дополнительное поле funct, для определения конкретной операции. Все поля, использущиеся в данных типах инструкций:

Rs,rt и rd – индикаторы задействования регистров, shamt – параметр сдвига,а поле address/immediate явно содержит операнд.

Пример: сложение значений в регистрах 1 и 2 и запись результата в регистр 6:

Пример: загрузка значения в регистр 8, взятое из ячейки памяти, находящейся на 68 ячеек дальше, чем адрес, находящийся в регистре 3:

Пример: переход к адресу 1024:

Пример для x86 (MS DOS) – “Hello, World!”

Программа «Hello, world!» для процессора архитектуры x86 (ОС MS-DOS, вывод при помощи BIOS прерывания int 10h) выглядит следующим образом (в шестнадцатеричном представлении):

BB 11 01 B9 0D 00 B4 0E 8A 07 43 CD 10 E2 F9 CD 20 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21

Данная программа работает при её размещении по смещению 10016. Отдельные инструкции выделены цветом:

Источник

В чем разница между собственным кодом, машинным кодом и кодом сборки?

В чем разница между ними? Они одинаковы?

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

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

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

То, что вы видите, когда используете Debug + Windows + Disassembly при отладке программы на C #, является хорошим руководством для этих терминов. Вот его аннотированная версия, когда я компилирую программу hello world, написанную на C #, в конфигурации Release с включенной оптимизацией JIT:

Щелкните окно правой кнопкой мыши и установите флажок «Показать байты кода», чтобы получить аналогичное отображение.

Я не аннотировал его, в основном потому, что он очень похож на машинный код, сгенерированный программой C #. Вызов функции printf () сильно отличается от вызова Console.WriteLine (), но все остальное примерно то же самое. Также обратите внимание, что отладчик теперь генерирует реальный адрес машинного кода и что он немного умнее относится к символам. Побочный эффект генерации отладочной информации после генерации машинного кода, как часто делают неуправляемые компиляторы. Я также должен упомянуть, что я отключил несколько параметров оптимизации машинного кода, чтобы машинный код выглядел похожим. Компиляторы C / C ++ имеют намного больше времени для оптимизации кода, результат часто трудно интерпретировать. И очень сложно отлаживать.

Источник

машинный код и байт код отличие. 220px W65C816S Machine Code Monitor. машинный код и байт код отличие фото. машинный код и байт код отличие-220px W65C816S Machine Code Monitor. картинка машинный код и байт код отличие. картинка 220px W65C816S Machine Code Monitor. V8 — это JavaScript-движок Google с открытым кодом. Его используют Chrome, Node.js и многие другие приложения. Этот материал, подготовленный сотрудником Google Франциской Хинкельманн, посвящён описанию формата байт-кода V8. Байт-код довольно просто читать, если понять некоторые базовые вещи.

СОДЕРЖАНИЕ

Набор инструкций

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

Программ

На выполнение программы могут влиять специальные инструкции «перехода», которые передают выполнение на адрес (и, следовательно, инструкцию), отличный от следующего числового последовательного адреса. Возникновение этих условных переходов зависит от такого условия, как значение, которое больше, меньше или равно другому значению.

Языки ассемблера

Пример

Например, сложение регистров 1 и 2 и помещение результата в регистр 6 кодируется:

Загрузите значение в регистр 8, взятое из ячейки памяти 68 ячеек после ячейки, указанной в регистре 3:

Переход по адресу 1024:

Связь с микрокодом

Использование микрокода для реализации эмулятора позволяет компьютеру представить архитектуру совершенно другого компьютера. Линия System / 360 использовала это, чтобы позволить переносить программы с более ранних машин IBM на новое семейство компьютеров, например, эмулятор IBM 1401/1440/1460 на IBM S / 360 model 40.

Связь с байт-кодом

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

Хранение в памяти

Читаемость людьми

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *