справочник машинных кодов ассемблера
FE23 LOOCH DISASM
СПРАВОЧНИК ПО КОМАНДАМ
ПРОЦЕССОРОВ x86
Главная | Загрузка | Инструкция | Команды x86 | Карта сайта |
СПРАВОЧНИК ПО КОМАНДАМ |
Главная | Загрузка | Инструкция | Команды x86 | Карта сайта |
КОМАНДЫ АССЕМБЛЕРА |
Главная | Загрузка | Инструкция | Команды x86 | Карта сайта |
СТРУКТУРА МАШИННОЙ КОМАНДЫСтруктура машинной командыСтруктура машинной команды для режима «32 бита»Каждая машинная команда может содержать от одного байта до 16 байт. Примечание. Есть две машинных команды (CALL, код 9A, JMP, код EA), в которых поле для задания адреса занимает 6 байт. Структура машинной команды для режима «16 бит»Примечание. Есть две машинных команды (CALL, код 9A, JMP, код EA), в которых поле для задания адреса занимает 4 байта. Префиксы перед кодом операцииВообще-то префиксы перед командами встречаются не часто. Чтобы в этом убедиться, достаточно посмотреть на какую-нибудь распечатку программы в виде машинных команд, например, на результаты работы дизассемблера. Еще более редко можно увидеть сразу два префикса подряд. Когда перед кодом операции помещаются префиксы, должны соблюдаться следующие два правила: Если в команде есть более одного префикса, то префиксы должны располагаться в том порядке, в котором они показаны в таблицах, приведенных выше. В одной команде не могут стоять сразу два префикса одной группы (сразу два префикса команды или сразу два префикса замены сегмента). Замечено, что процессоры обычно бывают терпимы к нарушению этих правил. Однако, стоит все же считать, что результат таких нарушений может оказаться непредсказуемым. Префикс действует только в пределах той команды, перед которой он стоит. Префиксы командыПрефиксы команды имеют свои собственные имена на языке ассемблера. И вдобавок, некоторые ассемблеры показывают эти команды в отдельной строке. Поэтому при программировании на ассемблере эти префиксы команды могут восприниматься как самостоятельные команды. (Это еще раз показывает, что мышление на языке ассемблера может сильно отличаться от мышления на языке машинных команд). Префикс изменения размера адресаЕсли общий режим выполнения программы равен «32 бита», то для команды, перед которой есть префикс 67, устанавливается атрибут размера адреса «16» бит. Если общий режим выполнения программы равен «16 бит», то для команды, перед которой есть префикс 67, устанавливается атрибут размера адреса «32» бита. Действие префикса зависит от конкретной команды. Префикс изменения размера операндаЕсли общий режим выполнения программы равен «32 бита», то для команды, перед которой есть префикс 66, устанавливается атрибут размера операнда «16» бит. Если общий режим выполнения программы равен «16 бит», то для команды, перед которой есть префикс 66, устанавливается атрибут размера операнда «32» бита. Действие префикса зависит от конкретной команды. Префиксы замены сегментаКод операцииПосле всех префиксов (если перед командой есть префиксы) начинается собственно машинная команда. И начинается машинная команда с кода операции. Поле с кодом операции всегда присутствует в любой машинной команде. Очевидно, что в команде должен быть хотя бы один байт. И тогда этим единственным байтом как раз будет именно код операции. При обсуждении системы команд удобно использовать понятие «основной байт» кода операции. Если КОП состоит из одного байта, то этот байт и является основным байтом. Если КОП состоит из двух байт, то основным следует считать второй байт кода операции. В данном справочнике имеются таблицы команд, в которых команды расположены в порядке их кодов операции: Первый байт кода операций Второй байт кода операций В таблицах справочника в колонке «Формат» основной байт кода операции условно показан в виде восьми черточек, соотвествующих восьми разрядам основного байта. Подобное обозначение основного байта есть для каждой команды, так как у каждой команды есть код операции. Для многих команд в основном байте есть особые биты или битовые поля. Такие места в байте показаны буквами на фоне черточек. Разберем какой-нибудь конкретный случай. Пусть это будет команда ADD с кодами 04 и 05, которая выполняет операцию сложения. Двоичная запись для этих кодов операции выглядит так: 00000100 и 00000101, отличие только в самом младшем разряде. Здесь вариант команды ADD с кодом 04 выполняет операцию сложения для байта (размер операнда 8 бит), а вариант с кодом 05 выполняет ту же операцию для слова (размер 16 бит). Обозначение говорит о том, что прямо в основном байте кода операции задается регистр, для которого эта операция выполняется. И это значит, что для данной команды имеется восемь разных вариантов с разными кодами операций. Примерами таких команд могут служить однобайтные команды INC и DEC (инкремент и декремент). Можно посмотреть и с другой стороны, со стороны команд ассемблера. Если для команды INC задается в качестве операнда какой-нибудь регистр, например EAX или EBX, то операнд будет указан прямо в коде операции машинной команды. Байт MRM имеется не во всех командах. Это определяется конкретным кодом операции (а говоря точнее, «основным кодом операции»), входит ли байт MRM в состав данной машинной команды или не входит.
Обозначение NNNДело в том, что основной код операции (один байт или два байта) не всегда однозначно определяет, какая это команда. При некоторых значениях основного кода операции к этому коду операции добавляются еще три бита из поля байта MRM. И тогда уже этот рассширенный код операции определяет команду. В таблицах данного справочника для подобных команд ставится обозначение NNN в колонке «Формат» вместо обозначения MRM. Просто нужно было как-то выделить отдельно этот особый случай. Вот и получился «байт NNN» вместо «байта MRM». Для этих случаев в таблицах справочника тоже ставится обозначение NNN. Байт SIB возможен в команде только в режиме 32 бита и только в том случае, когда в команде уже есть байт MRM (в полной форме или в сокращенной форме NNN). Этот дополнительный байт для задания режима адресации включается в состав команды только при некоторых определенных значениях в полях и байта MRM. Аналогично байту MRM, байт SIB делится на три битовых поля:
Байт SIB позволяет применять еще более сложные формы задания адреса в памяти. Поле для задания адресаВ этом поле из 1, или 2, или 4 байт, расположенном внутри команды, может быть задан либо полный адрес, либо смещение относительно некоторого адреса. С точки зрения терминологии, не всегда можно отличить «смещение» от «полного адреса». Например, как называть полный адрес внутри сегмента, если такой адрес всегда задается смещением от начала сегмента. Эти два разных случая по-разному отражаются в таблицах справочника в колонке «Формат». Если в формате команды есть обозначение MRM (или обозначение NNN), то дополнительные байты, относящиеся к байту MRM никак не показываются. Так что поле для задания адреса в этом случае показано не будет. Поле для задания адреса есть не во всех машинных командах. Непосредственный операндФорматы многих команд предусматривают возможность задавать константу непосредственно внутри команды. На языке ассемблера это соответствует заданию для операнда конкретного численного значения вместо имени переменной. Поле для непосредственного операнда есть не во всех машинных командах. Если в формате команды есть поле для задания непосредственного операнда, то это поле в команде всегда будет последним. Все страницы справочникаСамые последние новые страницы, добавленные в справочник, могут отсутствовать в этом списке. Но все новые страницы заведомо есть в списке на главной странице. Структура машинной командыСмотрите также страницы справочника: СодержаниеСтруктура машинной командыСтруктура машинной команды для режима «32 бита»Каждая машинная команда может содержать от одного байта до 16 байт. Примечание. Есть две машинных команды (CALL, код 9A, JMP, код EA), в которых поле для задания адреса занимает 6 байт. Структура машинной команды для режима «16 бит»Примечание. Есть две машинных команды (CALL, код 9A, JMP, код EA), в которых поле для задания адреса занимает 4 байта. Префиксы перед кодом операцииВообще-то префиксы перед командами встречаются не часто. Чтобы в этом убедиться, достаточно посмотреть на какую-нибудь распечатку программы в виде машинных команд, например, на результаты работы дизассемблера. Еще более редко можно увидеть сразу два префикса подряд. Когда перед кодом операции помещаются префиксы, должны соблюдаться следующие два правила: Если в команде есть более одного префикса, то префиксы должны располагаться в том порядке, в котором они показаны в таблицах, приведенных выше. В одной команде не могут стоять сразу два префикса одной группы (сразу два префикса команды или сразу два префикса замены сегмента). Замечено, что процессоры обычно бывают терпимы к нарушению этих правил. Однако, стоит все же считать, что результат таких нарушений может оказаться непредсказуемым. Префикс действует только в пределах той команды, перед которой он стоит. Код префикса не может совпадать с кодом операции какой-нибудь команды. Это хорошо видно по таблице Первый байт кода операций. В этой таблице показаны также и коды префиксов. Префиксы командыПрефиксы команды имеют свои собственные имена на языке ассемблера. И вдобавок, некоторые ассемблеры показывают эти команды в отдельной строке. Поэтому при программировании на ассемблере эти префиксы команды могут восприниматься как самостоятельные команды. (Это еще раз показывает, что мышление на языке ассемблера может сильно отличаться от мышления на языке машинных команд). Префикс изменения размера адресаЕсли общий режим выполнения программы равен «32 бита», то для команды, перед которой есть префикс 67, устанавливается атрибут размера адреса «16» бит. Если общий режим выполнения программы равен «16 бит», то для команды, перед которой есть префикс 67, устанавливается атрибут размера адреса «32» бита. Действие префикса зависит от конкретной команды. Префикс изменения размера операндаЕсли общий режим выполнения программы равен «32 бита», то для команды, перед которой есть префикс 66, устанавливается атрибут размера операнда «16» бит. Если общий режим выполнения программы равен «16 бит», то для команды, перед которой есть префикс 66, устанавливается атрибут размера операнда «32» бита. Действие префикса зависит от конкретной команды. Префиксы замены сегментаКод операцииПосле всех префиксов (если перед командой есть префиксы) начинается собственно машинная команда. И начинается машинная команда с кода операции. Поле с кодом операции всегда присутствует в любой машинной команде. Очевидно, что в команде должен быть хотя бы один байт. И тогда этим единственным байтом как раз будет именно код операции. При обсуждении системы команд удобно использовать понятие «основной байт» кода операции. Если КОП состоит из одного байта, то этот байт и является основным байтом. Если КОП состоит из двух байт, то основным следует считать второй байт кода операции. В данном справочнике имеются таблицы команд, в которых команды расположены в порядке их кодов операции: Первый байт кода операций Второй байт кода операцийВ таблицах справочника в колонке «Формат» основной байт кода операции условно показан в виде восьми черточек, соотвествующих восьми разрядам основного байта. Подобное обозначение основного байта есть для каждой команды, так как у каждой команды есть код операции. Для многих команд в основном байте есть особые биты или битовые поля. Такие места в байте показаны буквами на фоне черточек. Разберем какой-нибудь конкретный случай. Пусть это будет команда ADD с кодами 04 и 05, которая выполняет операцию сложения. Двоичная запись для этих кодов операции выглядит так: 00000100 и 00000101, отличие только в самом младшем разряде. Здесь вариант команды ADD с кодом 04 ( w = 0 ) выполняет операцию сложения для байта (размер операнда 8 бит), а вариант с кодом 05 ( w = 1 ) выполняет ту же операцию для слова (размер 16 бит). Обозначение ( ——reg ) говорит о том, что прямо в основном байте кода операции задается регистр, для которого эта операция выполняется. И это значит, что для данной команды имеется восемь разных вариантов с разными кодами операций. Примерами таких команд могут служить однобайтные команды INC и DEC (инкремент и декремент). Можно посмотреть и с другой стороны, со стороны команд ассемблера. Если для команды INC задается в качестве операнда какой-нибудь регистр, например EAX или EBX, то операнд будет указан прямо в коде операции машинной команды. Полный список обозначений для особых битов и битовых полей основного байта приведен на странице Пояснения к основным таблицам. Байт MRM имеется не во всех командах. Это определяется конкретным кодом операции (а говоря точнее, «основным кодом операции»), входит ли байт MRM в состав данной машинной команды или не входит. Здесь важно заметить, что речь идет не о команде с точки зрения языка ассемблера, а о машинной команде с конкретным основным кодом операции. Например, команда сложения ADD имеет четыре разных варианта с байтом MRM, еще четыре варианта с «сокращенным» байтом MRM, который в нашем справочнике обозначен как NNN, и два варианта вообще без байта MRM. Итого это получается десять разных кодов операции, десять разных вариантов машинной команды. См. страницу Основные команды арифметики. В таблицах справочника, в колонке «Формат» показано, в составе каких команд есть байт MRM. Причем наличие в колонке «Формат» обозначения MRM или обозначения NNN говорит о том, что в составе команды есть целая группа байтов, относящаяся к MRM. Первым в этой группе идет байт ( mod,reg,r/m ), то есть, собственно байт MRM, затем, если требуется, может идти второй байт режима адресации, это байт SIB, а затем, если требуется, может быть еще и поле для задания адреса. Байт MRM делится на три битовых поля: двухбитовое поле ( mod ), трехбитовое поле ( reg ), трехбитовое поле ( r/m ).
Поле ( reg ) определяет первый операнд команды, операнд-приемник (destination). Поле ( r/m ) определяет второй операнд команды, операнд источник (source). Обычно бывает именно такое распределение ролей между ( reg ) и ( r/m ), который из операндов будет источником, а который приемником. Но бывает и наоборот, это зависит от конкретной команды. Поле ( r/m ) задает либо регистр, либо память. Это поле действует совместно с полем ( mod ), вместе будет пять битов и получается 32 варианта, это дает 8 вариантов для задания регистров и 24 варианта для задания формы и режима адресации памяти. Обозначение NNNВ системе команд x86 имеются такие команды, в которых байт MRM используется несколько иначе, чем было описано выше. Отличие в том, как трактуется поле ( reg ). Дело в том, что основной код операции (один байт или два байта) не всегда однозначно определяет, какая это команда. При некоторых значениях основного кода операции к этому коду операции добавляются еще три бита из поля ( reg ) байта MRM. И тогда уже этот рассширенный код операции определяет команду. Как пример такого случая, можно назвать команды с первым байтом кода операции равным 80, 81, 82, 83. См. страницу Первый байт кода операций. В таблицах данного справочника для подобных команд ставится обозначение NNN в колонке «Формат» вместо обозначения MRM. Просто нужно было как-то выделить отдельно этот особый случай. Вот и получился «байт NNN» вместо «байта MRM». Обозначение NNN показывает, что в команде стоит сокращенный вариант байта MRM, который может задавать только один операнд, вместо прежних двух операндов. Этот операнд определяется полями ( mod ) и ( r/m ), так что операнд может быть либо регистром, либо может иметь одну из многих форм задания адреса в памяти. В системе команд x86 есть случаи, когда байт MRM применяется в сокращенном виде только из-за того, что для данной конкретной команды не требуется, чтобы байт MRM задавал два операнда, так как в этой команде нужен только один операнд. В этом случае поле ( reg ) байта MRM просто не используется, а в документации оговаривается, что всегда должно быть ( reg = 0 ). Таких случаев совсем немного: Для этих случаев в таблицах справочника тоже ставится обозначение NNN. Байт SIB возможен в команде только в режиме 32 бита и только в том случае, когда в команде уже есть байт MRM (в полной форме или в сокращенной форме NNN). Этот дополнительный байт для задания режима адресации включается в состав команды только при некоторых определенных значениях в полях ( mod ) и ( r/m ) байта MRM. Аналогично байту MRM, байт SIB делится на три битовых поля:
Байт SIB позволяет применять еще более сложные формы задания адреса в памяти. Поле для задания адресаВ этом поле из 1, или 2, или 4 байт, расположенном внутри команды, может быть задан либо полный адрес, либо смещение относительно некоторого адреса. С точки зрения терминологии, не всегда можно отличить «смещение» от «полного адреса». Например, как называть полный адрес внутри сегмента, если такой адрес всегда задается смещением от начала сегмента. Поле задания адреса может по-разному использоваться в разных командах. Однако, рассматривая общую структуру команды, важно различать следующие два случая: Эти два разных случая по-разному отражаются в таблицах справочника в колонке «Формат». Если в формате команды есть обозначение MRM (или обозначение NNN), то дополнительные байты, относящиеся к байту MRM никак не показываются. Так что поле для задания адреса в этом случае показано не будет. Если в формате команды нет байта MRM, но есть поле для задания адреса, то в колонке «Формат» будет стоять обозначение «addr (..)«, где в скобках указывается количество байт. В системе команд x86 невозможен случай, чтобы в некоторой команде оказалось сразу два поля для задания адреса. Поэтому в таблицах справочника невозможен случай, чтобы в колонке «Формат» стояло обозначение MRM (или NNN), а затем еще и обозначение «addr (..)». Поле для задания адреса есть не во всех машинных командах. Непосредственный операндФорматы многих команд предусматривают возможность задавать константу непосредственно внутри команды. На языке ассемблера это соответствует заданию для операнда конкретного численного значения вместо имени переменной. В таблицах справочника в колонке «Формат» наличие непосредственного операнда показано обозначением «data (..)«, где в скобках указывается количество байт. Поле для непосредственного операнда есть не во всех машинных командах. Если в формате команды есть поле для задания непосредственного операнда, то это поле в команде всегда будет последним.
|