Спецификации для 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 кода операции