Формат машинных команд IA-32
🕛 17.09.2009, 13:27
Машинная команда представляет собой закодированное по определенным правилам указание процессору на выполнение некоторой операции. Правила кодирования команд называются форматом команд. Команды процессоров архитектуры IA-32 считаются сложными. Максимальная длина машинной команды IA-32 составляет 15 байт. Реальная команда может содержать гораздо меньшее количество полей, вплоть до одного - только код операции. Приведенный на рис. 3.1 формат машинной команды является наиболее полным.Как на уровне формата машинной команды соответствуют между собой машинные команды и команды ассемблера? Для примера рассмотрим типичную команду языка ассемблера: tnov ebx, eax
Команда M0V производит копирование содержимого регистра ЕАХв регистр ЕВХ. Соответствующая машинная команда будет выглядеть так:
88 D8
Значение 8В - код операции. Еще один пример команды M0V: mov ecx, 128
Данная команда инициализирует содержимое регистра ЕСХ десятичным значением 128. Соответствующая машинная команда выглядит так:
89 00000080
Значение поля с кодом операции - В9. Из примеров видно, что прямого соответствия между структурой команды ассемблера и соответствующей машинной командой нет. Несмотря на то, что команда ассемблера одна и та же (M0V), коды машинных команд - разные (8В и В9). Большинство команд ассемблера имеют несколько возможных вариантов сочетания операндов. Как показано в приведенных примерах, несмотря на одинаковые названия команд ассемблера, для
каждого возможного сочетания операндов имеется своя машинная команда, со своим значением поля кода операции (рис. 3.1). Это говорит о том, что машинная команда всегда однозначна по отношению к производимым ею действиям на уровне аппаратуры. Несколько упрощая реальность, можно утверждать, что значение в поле кода операции является номером микропрограммы в блоке микропрограммного управления для каждой конкретной команды ассемблера с каждым конкретным вариантом сочетания операндов.
Логически любая команда языка ассемблера содержит несколько элементов.
ш Элемент," описывающий, что делать, называется кодом операции (КОП). Значение в поле кода операции некоторым образом определяет в блоке микропрограммного управления подпрограмму, реализующую действия для данной команды.
в Элементы, описывающие объекты, с которыми нужно что-то делать, являются операндами. Операнды в команде могут и не задаваться, а подразумеваться по умолчанию.
и Элементы, описывающие, как делать, являются типами операндов и обычно задаются неявно. Они используются транслятором ассемблера при формировании машинной команды для определения значения поля кода операции.
Эти же элементы имеет и машинная команда, но в закодированном виде. Перевод команд ассемблера в соответствующие машинные команды осуществляет специальная программа - ассемблер, которую можно также назвать транслятором (компилятором) ассемблера.
Опишем назначения полей машинной команды.
Поле префиксов
Префиксы - необязательные однобайтные элементы машинной команды. Назначение префиксов - изменить действия, выполняемые командой. Префиксы могут указываться программистом явно при написании исходного текста программы, либо их, по определенным соображениям, может вставить ассемблер. Процессор распознает префиксы по их значениям. Машинная команда может иметь до четырех префиксов одновременно. В памяти префиксы предшествуют команде. Порядок их следования при этом может быть любым.Далее перечислены типы префиксов, которые может использовать прикладная программа.
* Префикс замены сегмента в явной форме указывает, какой сегментный регистр используется в данной команде для адресации стека или данных. Префикс отменяет выбор сегментного регистра по умолчанию. Префиксы замены сегмента имеют следующие значения:
2Eh - замена сегмента CS;
36h - замена сегмента SS;
ЗЕК - замена сегмента DS;
26h - замена сегмента ES;
64h - замена сегмента FS;
65h - замена сегмента GS.
Префикс повторения используется с цепочечными командами (командами обработки строк). Этот префикс «зацикливает» команду для обработки всех элементов цепочки. Система команд поддерживает два типа префиксов: безусловные (REP - 0F3h), заставляющие цепочечную команду повторяться некоторое количество раз, и z/c/?oewwe(REPE/REPZ - OF3h, REPNE/REPNZ - OF2h), которые при зацикливании проверяют некоторые флаги, и в результате проверки возможен досрочный выход из цикла.
Префикс блокировки шины инициирует выдачу процессором сигнала L0CK# (значение OFOh) для блокировки системной шины. Используется в многопроцессорных конфигурациях для обеспечения монопольного владения системной шиной. Сигнал ШСК# может формироваться лишь с определенной номенклатурой команд процессора, работающих в цикле «чтение-модификация-запись».
Префикс размера адреса (значение 67h) уточняет разрядность адреса: 16 или 32 бита. Каждой команде, в которой используется адресный операнд, ставится в соответствие разрядность адреса этого операнда. Если разрядность адреса для данной команды составляет 16 битов, это означает, что команда содержит 16-разрядное смещение и оно соответствует 16-разрядному смещению адресного операнда относительно начала некоторого сегмента (см. рис. 3.1). В контексте материала главы 2 (см. рис. 2.7 и 2.8) это смещение называется эффективным адресом. Если разрядность адреса составляет 32 бита, это означает, что команда содержит 32-разрядное смещение, оно соответствует 32-разрядному смещению адресного операнда относительно начала сегмента и по его значению формируется 32-разрядное смещение в сегменте (см. рис. 3.1). С помощью префикса разрядности адреса можно изменить действующее по умолчанию значение разряд-. ности адреса. Это изменение будет касаться только той команды, которой предшествует префикс. - Префикс размера операнда (значение 66h) аналогичен префиксу размера адреса, но указывает на разрядность операндов (32 или 16 битов), с которыми работает команда.
По каким правилам устанавливаются по умолчанию значения атрибутов разрядности адреса и операндов? Если команда имеет операнд в памяти, то его адрес представляет собой значение смещения относительно начала сегмента данных (если не используется префикс переопределения сегмента) и содержится в поле смещения машинной команды. Размер этого поля зависит от текущего режима адресации (атрибуты usel6 или use32 в директивах сегментации). При 16-разрядной адресации размер поля смещения в машинной команде составляет 16 битов. При 32-разрядной адресации размер поля смещения в машинной команде составляет 32 бита. Явное задание префикса размера адреса позволяет указать процессору значение, отличающееся от действующего по умолчанию. Например, если действующий размер адреса равен 16 битам, то использование перед какой-либо командой префикса 67h определит для нее (и только для нее!) размер адреса в 32 бита. И наоборот, если действующий размер адреса равен 32 бита, то указание перед командой префикса 67h определит для нее (и только для нее!) размер адреса в 16 битов. Физически это будет отражаться на размере поля смещения в данной машинной команде.
Префикс размера операнда 66h позволяет сменить действующий для данной команды атрибут размера операнда. Команда, которая по умолчанию работает со словом (16 битов) или с двойным словом (32 бита), имеет атрибут размера операнда, равный 16 и 32 бита соответственно. Применение префикса размера операнда позволяет сменить действующий по умолчанию атрибут.
При работе процессора i8086в реальном и виртуальном режимах атрибуты размера адреса и операнда по умолчанию равны 1ббитов. В защищенном режиме значения этих атрибутов зависят от значения бита D дескриптора сегмента. Если D = 0, то атрибуты размера адреса и операнда равны 16 битов, если D = 1, то эти атрибуты равны 32 бита. Изменить действующие по умолчанию атрибуты адреса и размера операндов можно применением атрибутов usel6 или use32 в директивах сегментации.
В реальном режиме с помощью префикса разрядности адреса можно задействовать 32-разрядную адресацию, но при этом необходимо помнить об ограниченности размера сегмента величиной 64 Кбайт. Аналогично префиксу разрядности адреса можно использовать префикс разрядности операнда в реальном режиме для работы с 32-разрядными операндами (к примеру, в арифметических командах).
В команде префиксы размера адреса и операнда могут указываться одновременно. Каким образом комбинация префиксов (указанных явно и установленных по умолчанию) влияет на атрибуты размера операнда и адреса машинной команды, показано в табл. 3.1. В ней отражено и то, как влияет на эти атрибуты состояние бита D дескриптора сегмента в защищенном режиме. Строки таблицы, соотФормат машинных команд IA-32 63
ветствующие нулевому значению бита D, используются в реальном и виртуальном режимах работы процессора i8086.
Необходимо обратить внимание на то, что команды работы со стеком также имеют аналогичные атрибуты размера и адреса операнда. Атрибут размера адреса влияет на выбор регистра - указателя стека: при размере адреса 16 битов используется регистр SP, при размере адреса 32 бита используется регистр ESP. Аналогично влияет на работу команд со стеком префикс размера операнда: при использовании префикса размера операнда 16 битов операнд в стеке трактуется как 16-разрядный, при использовании префикса размера операнда 32 бита операнд в стеке трактуется как 32-разрядный.
В качестве примера префикса, который при формировании машинной команды вставляет сам ассемблер, можно привести префикс со значением OFFh. Он называется префиксом смены алфавита и извещает о том, что поле кода операции в данной команде двухбайтовое.
Код операции
Код операции - обязательный элемент, описывающий операцию, выполняемую командой. Код операции может занимать от одного до трех байт. Для некоторых машинных команд часть битов кода операции может находиться в байте mod r/m.Многим командам соответствует несколько кодов операций, каждый из которых определяет нюансы выполнения операции. Отметим, что поле кода операции не имеет однозначной структуры (см. рис. 3.1). В зависимости от конкретных команд, не обязательно разных с точки зрения языка ассемблера, оно может иметь в своем составе от одного до трех элементов, назначение которых описано в табл. 3.2. Один из этих трех элементов является непосредственно кодом операции или ее частью, остальные уточняют детали операции. Такое строение поля кода операции усложняет, в частности, процесс дизассемблирования. Для определения размера и границ очередной команды необходимо полностью проанализировать ее поле кода операции.
Определяет направление передачи данных: 0 - передача данных из регистра reg в память (или регистр), адресуемую полем т/т; 1 - передача данных из памяти (или регистра), адресуемой нолем r/m, в регистр reg. При наличии байта sib адрес операнда в памяти формируется с учетом содержимого этого байта
Задает необходимость расширения 8-разрядного непосредственного операнда до 16 или 32 бита. Старшие биты при этом заполняются значением старшего (знакового) бита исходного 8-разрядного операнда
Определяет размер данных, которыми оперирует команда: байт, слово, двойное слово: 0 - 8 битов; 1 - 16 битов для 16-разрядного размера операндов или 32 бита для 32-разрядного размера операндов
Определяет регистр, используемый в команде. Значение поля зависит от ноля w, в том числе если поле w отсутствует (см. следующий подраздел)
Последующие поля машинной команды определяют характеристики и местоположение операндов, участвующих в операции, и особенности их использования (см. далее).
Байт режима адресации mod r/m
Байт режима адресации mod r/m, иногда называемый постбайтом, несет информацию об операндах и режиме адресации. Большинство команд процессора Intel -двухоперандные. Операнды могут находиться в памяти, а также в одном или двух регистрах. Архитектура IA-32 не допускает, чтобы оба операнда команды находились в памяти. Если операнд находится в памяти, то байт mod r/m определяет компоненты (смещение, базовый и индексный регистры), используемые для вычисления его эффективного адреса (см. главу 2). Байт mod r/m состоит из трех полей.
Поле mod (два бита) определяет способ адресации и количество байтов, занима-емых в команде адресом операнда (поле смещения в команде). Поле mod используется совместно с полем r/m, которое определяет способ модификации адреса операнда полем смещения в команде. Поле mo d в комбинации с полем r/m образует 32 возможных значения, обозначающих один из восьми регистров и 24 режима адресации. К примеру, если mod = 00, то поле смещения в команде отсутствует и адрес операнда определяется содержимым базового и/или индексного регистра. Какие именно регистры потребуются для вычисления эффективного адреса, определяется значением этого байта. Если mod = 01, то поле смещения в команде присутствует, занимает один байт и модифицируется содержимым базового и/или индексного регистра. Если mod = 10, то поле смещения в команде присутствует, занимает два или четыре байта (в зависимости от значения, действующего по умолчанию или определяемого префиксом размера адреса)
и модифицируется содержимым базового и/или индексного регистра. Если mod = 11, то операндов в памяти нет - они находятся в регистрах. Это же значение байта mod используется в случае, когда команда работает с непосредственным операндом.
* Поле reg (3 бита) определяет либо регистр (табл. 3.3 и 3.4), находящийся в команде на месте второго операнда, либо возможное расширение кода операции (давая в совокупности размер поля КОП в 11 битов).
я Поле r/m используется совместно с полем mod и определяет либо регистр, находящийся в команде на месте первого операнда (если mod = 11), либо базовые и индексные регистры, применяемые для вычисления эффективного адреса (совместно с полем смещения в команде).
В таблицах нет содержимого поля reg для 16-разрядных регистров в 32-разрядных операциях, так как в архитектуре Intel отдельно использовать старшую половину 32-разрядного регистра невозможно.
В архитектуре Intel один из операндов обязательно находится в регистре, и он может быть первым или вторым. Расположение первого и второго операндов в формате команды фиксировано. Но, например, команда M0V может выполнять пересылку как из регистра в память, так и из памяти в регистр. В машинном представлении
это одна и та же команда. В ее поле reg будет содержаться код регистра (см. табл. 3.3 и 3.4), а в поле r/m - код режима адресации (см. далее). Эти две команды будут различаться только одним битом d, который определяет направление передачи. Если в команде участвуют два регистра, то в этом случае вступает в силу правило: поле reg определяет второй операнд, а поле r/m - первый. Если команда mov работает с ячейкой памяти, то в исходном тексте программы могут быть следующие варианты записи этой команды: mov abll.ax ;пересылка содержимого ах в ячейку памяти abll
или
mov ax,abll ;пересылка содержимого ячейки памяти abll в ах
В машинном представлении эти две команды будут выглядеть одинаково, за исключением бита d: ' для команды MOV abll,ax бит d = 0; ш для команды MOV ax,abll бит d = 1.
Наиболее сложными для декодирования являются команды с операндом в памяти. Фирма Intel сопровождает описание системы команд специальными таблицами, облегчающими интерпретацию содержимого байта mod r/m (табл. 3.5 и 3.6). С их помощью можно довольно легко восстановить компоненты, из которых формировался адрес операнда, и, в конечном итоге, восстановить соответствующую команду ассемблера для данной машинной команды. Значения байта mod r/m (16-разрядная адресация)
Рассмотрим пример использования данных таблиц при значении байта mod r/m равном 87h. Для восстановления местонахождения операндов данной машинной команды следует найти это значение в одной из таблиц (какой таблицей воспользоваться, зависит от текущего режима адресации) и по первому столбцу строки, содержащей код 87h, определить местонахождение первого операнда. В нашем случае адрес операнда формируется из содержимого регистра ВХ и 16-разрядного смещения, значение которого следует искать в следующих за байтом mod r/m двух байтах. Второй столбец той же строки содержит значение поля mod. Третье поле байта m o d r/m можнонайти.переместившись вверх по столбцу, содержащему значение 87h, до пересечения со строкой reg или /цифра. При этом будет выбрано значение, идентифицирующее один из регистров или продолжение кода операции. Что именно - определяется либо самим кодом операции, либо значением бита w в сочетании с текущей разрядностью адреса (см. ранее).
При использовании 32-разрядной адресации содержимое байта mod r/m трактуется несколько иначе из-за наличия в формате машинной команды байта sib (см. подраздел «Байт масштаба, индекса и базы»).
Некоторые машинные команды могут работать с сегментными регистрами. Далее приведены соглашения по кодированию сегментных регистров. В дальнейшем изложении будем различать два набора регистров:
sreg86 - сегментные регистры, существовавшие в архитектуре процессоров i8086/88и i80286; sreg386 - сегментные регистры архитектуры процессоров i80386 и выше.
Различие наборов состоит в том, что кодируются они различным количеством битов: sreg86 - двумя битами (табл. 3.7), a sreg386 - тремя. Кодировка сегментных регистров в наборе sreg86
Одна из целочисленных команд - команда MOV - может оперировать системными регистрами. Кодировка этих регистров приведена в табл. 3.9.
Таблица 3.9. Кодировка системных регистров в команде MOV
Код в поле creg
Байт масштаба, индекса и базы
Байт масштаба, индекса и базы (Scale-Index-Base - sib) используется для расширения возможностей адресации операндов. На наличие байта sib в машинной команде указывает сочетание одного из значений 01 или 10 поля mod и значения поля г/т = 100. Байт sib состоит из трех элементов.В поле масштаба (ss) размещается масштабный множитель для индексного компонента index, занимающего следующие три бита байта sib. В поле ss может содержаться значение 1, 2, 4 или 8. При вычислении эффективного адреса на это значение будет умножаться содержимое индексного регистра. Более подробно, с практической точки зрения, эта расширенная возможность индексации рассматривается при обсуждении массивов в главе 13.
Поле index позволяет хранить номер индексного регистра, содержимое которого применяется для вычисления эффективного адреса операнда.
и Поле base требуется для хранения номера базового регистра, содержимое которого также применяется для вычисления эффективного адреса операнда. В качестве базового и индексного регистров могут использоваться большинство регистров общего назначения.
По значению байта sib легко восстановить компоненты машинных команд, содержащие адрес операнда с учетом его масштабирования.
Одно значение базового регистра (base) в табл. 3.10 замещено символом звездочки (*). Это означает наличие в команде адреса смещ_32 без базы, если mod равно 00, и [ЕВР] - в противном случае. Такой подход обеспечивает следующие режимы адресации:
и смещ_32[индекс], если mod=00; и смещ_8[еЬр][индекс], если mod=01; II смещ_32[еЬр][индекс], если mod=10,
Поля смещения и непосредственного операнда
Поле смещения в команде - это 8-, 16- или 32-разрядное целое число со знаком, представляющее собой полностью или частично (с учетом приведенных ранее рассуждений) значение эффективного адреса операнда.
Поле непосредственного операнда - необязательное поле, представляющее собой 8-, 16- или 32-разрядный непосредственный операнд. Наличие этого поля, конечно, отражается на значении байта mod r/m.
Столь подробное обсуждение различных полей машинной команды, в том числе с использованием всех приведенных ранее таблиц, имеет целью показать правила формирования операндов машинных команд. При рассмотрении синтаксиса ассемблера (глава 5) на основе этого материала будут обсуждаться правила записи операндов команд ассемблера.
Функциональная классификация машинных команд
В начале главы отмечалось, что система команд последнего на сегодняшний день процессора Pentium IV архитектуры IA-32 содержит более 300 машинных команд. Весь набор машинных команд можно разбить на четыре группы (рис. 3.2).
Команды ассемблера Pentium IV
Процессора
Сопроцессора
MMX-расширения
ХММ-расширения
Машинные команды процессора Intel (Pentium IV)
В пределах каждой из этих больших групп, исходя из функционального назначения отдельных команд, можно провести дальнейшее разбиение на более мелкие подгруппы. Такой подход позволяет достичь нескольких целей: оценить возможности процессора по обработке данных; рассмотреть совокупность команд процессора архитектуры IA-32 как иерархическую и самодостаточную систему; осмысленно изучать отдельные машинные команды в контексте остальных.
будут рассмотрены команды основного процессора (целочисленные), поэтому здесь приведем их классификацию по функциональному признаку ).
Команды ассемблера I
Пересылки данных
Арифметические
Общего назначения
Работы со стеком
Логические
Двоичной арифметики
Десятичной арифметики
Передачи Управления
Манипуляции битами
Сдвига
Цепочечные
Управления состоянием ЦП
Безусловные
Условные
Работы с флагами
Преобразования _данных
Работы с - системными [ регистрами Функциональная классификация целочисленных машинных команд
Функциональная классификация команд остальных групп будет приведена в материале соответствующих глав. Информацию о каждой команде процессора архитектуры IA-32 (вплоть до Pentium IV) можно найти в приложении, которое удобно использовать в ходе работы над программными проектами. Стоит обратить внимание на то, что приложение состоит из четырех Частей - это соответствует разбиению команд процессора на функциональные группы .
Итоги
Система машинных команд - важнейшая часть архитектуры компьютера, определяющая возможности его программирования.Для работы процессора достаточно программы в двоичных кодах, но такое прямое программирование на практике не используется. Язык ассемблера - символический аналог машинного языка. Преобразование команд ассемблера в соответствующие машинные команды производит программа-транслятор - ассемблер. Дальнейшая интерпретация машинных команд в конкретные сигналы электронных схем осуществляется с помощью блока микропрограммного управления, входящего в состав процессора.
Существует взаимно однозначное соответствие машинных команд и команд ассемблера.
Кодирование машинных команд производится в соответствии с одним из возможных форматов. Команды процессоров архитектуры IA-32 считаются сложными, так как в основу концепции процессоров 1п1е1положен принцип совместимости - программы, разработанные для более ранних моделей процессоров, должны выполняться на всех последующих.
Структура команд процессора позволяет обеспечить большую гибкость при
обработке операндов и разнообразие режимов адресации.
к Большинство команд ассемблера имеют несколько возможных вариантов сочетания операндов. Для каждого возможного сочетания операндов имеется своя машинная команда со своим значением поля кода операции.
Машинную команду формируют несколько полей, из которых обязательным является только одно - поле кода операции.
Система команд архитектуры IA-32 является иерархической и самодостаточной. Все команды делятся на четыре группы, в пределах каждой из которых выделяется довольно большое количество функциональных подгрупп.