Спецификации для MOV оп-кодов

Во всей документации, которую я могу найти относительно кодов операций для мнемоники MOV, каждый код операции не документируется отдельно. оп-код B8h+ Документируется как перемещение 16- или 32-разрядных данных в 16- или 32-разрядный реестр. Что именно касается реестра, определяется тем, насколько далеко выше B8h код операции есть. То есть, чтобы получить код операции для инструкции MOV B8h типа, вы берете B8h и добавьте номер регистра. Проблема в том, что я не нахожу никакой информации о количестве каждого реестра. Следующее мое предположение, но я не уверен.

Регистр назначения. Op-код.

AX  B8

CX  B9

DX  BA

BX  BB

EAX BC

ECX BD

EDX BE

EBX BF

1 ответ

В вашей таблице есть ошибка: 16- и 32-битный размер операнда имеют одинаковый код операции и дифференцируются байтом префикса размера операнда, чтобы использовать тот, который в настоящее время не является размером операнда по умолчанию. (Таким образом, 16-битные инструкции занимают дополнительный байт в 32-битном и 64-битном режиме.) Это верно для всех кодов операций, а не только mov,

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

Для большинства инструкций существуют отдельные коды операций для 8 против 16/32/64, но я думаю, что места для кода операции было недостаточно для добавления другой версии всего, когда произошло расширение с 16 до 32 бит.

  • mov r8, imm8 использует код операции B0+rb (так, B0-B7).
  • mov r16/32/64, imm16/32/64 использует код операции B8+rw/rd (так, B8-BF), либо с префиксом размера операнда, с префиксом REX с установленным битом.W), либо без префикса.

Поскольку мы находимся на теме, стоит упомянуть, что mov r/m64, imm32 (расширенный знак-немедленный) должен использовать дополнительный байт для кодирования регистра назначения или эффективного адреса, но он все еще короче mov r64, imm64, В синтаксисе AT&T вы должны использовать movabs мнемоника, если вы хотите, иначе ассемблер урезает вашу константу до 32 бит.


Фактические двоичные кодировки для номеров регистров, по-видимому, указаны в трех местах в справочных руководствах Intel, том 2. (по ссылке из вики x86).

Наиболее актуальный для этого вопроса (регистр закодирован как последние 3 бита кода операции), есть таблица 3-1. Зарегистрируйте коды, связанные с + rb, + rw, + rd, + ro, внутри Раздела 3.1: ИНТЕРПРЕТАЦИЯ СТРАНИЦ ИНСТРУКЦИИ.

Кодировки такие же, как в Приложении B.1.3, в котором снова указывается, что 3-битное поле регистра может быть последними 3 битами кода операции. (Я думаю, все коды операций, которые используют +rb / +rd кратны 8, поэтому добавление 0-7 = установка последних 3 бит). В B.1.4.1 имеются таблицы, в которых регистрируется каждое возможное выбранное 3-битное значение для размеров операндов 16 и 32 бит (в не 64-битном режиме).

Идет:

encoding | 8bit reg | 32bit reg 
000  |       AL   |      EAX
001  |       CL   |      ECX
010  |       DL   |      EDX
011  |       BL   |      EBX
100  |       AH   |      ESP
101  |       CH   |      EBP
110  |       DH   |      ESI
111  |       BH   |      EDI

Таблицы для других размеров операндов и для 64-битного режима находятся поблизости. (Инструкции с префиксом REX обычно не могут адресовать AH/BH/CH/DH, только младший байт из 16 регистров GP. Я думаю, это потому, что кодировка для ch сталкивается с bpl, при использовании с префиксом REX.)


В главе 2 также есть таблица кодировок регистров (для использования в полях mod / rm) с таблицами.

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

Глава 2.2.1.1: Кодирование (внутри секции IA-32e):

Форматы команд Intel 64 и IA-32 определяют до трех регистров, используя 3-битные поля в кодировке, в зависимости от формата:

  • ModR/M: поля reg и r/m байта ModR/M
  • ModR/M с SIB: поле reg байта ModR/M, поля base и index байта SIB (шкала, индекс, база)
  • Инструкции без ModR/M: поле reg кода операции
Другие вопросы по тегам