Ответ 1
Нет, вы не можете использовать 8-битные или 16-разрядные регистры для адресации вычислений в 64-битном режиме, а также не можете использовать 8-битные регистры в 32-битном режиме. Вы можете использовать 16-разрядные регистры в 32-битном режиме и 32-разрядные регистры в 64-битном режиме с использованием префиксного байта размера 0x67
.
В этой таблице хорошо представлены различные варианты размеров операндов и адресов. Общий шаблон состоит в том, что размер адреса по умолчанию такой же, как и текущий режим (т.е. 32-битный в 32-битном режиме, 64-битный в 64-битном режиме) 1 а затем, если Включен префикс 0x67
, размер адреса изменен на половину обычного размера (т.е. 16 бит в 32-битном режиме, 32 бит в 64-битном режиме).
Здесь выдержка из полной таблицы, связанной выше, показывающая только 64-битное поведение в режиме длинного режима, для различных значений операндов REX.W
, 0x66
и 0x67
:
╔════════╦═════════════╦═════════════╦═══════════════╦══════════════╗
║ REX.W ║ 0x66 prefix ║ 0x67 prefix ║ Operand size ║ Address size ║
║ ║ (operand) ║ (address) ║ (footnote 2) ║ ║
╠════════╬═════════════╬═════════════╬═══════════════╬══════════════╣
║ 0 ║ No ║ No ║ 32-bit ║ 64-bit ║
║ 0 ║ No ║ Yes ║ 32-bit ║ 32-bit ║
║ 0 ║ Yes ║ No ║ 16-bit ║ 64-bit ║
║ 0 ║ Yes ║ Yes ║ 16-bit ║ 32-bit ║
║ 1 ║ Ignored ║ No ║ 64-bit ║ 64-bit ║
║ 1 ║ ignored ║ Yes ║ 64-bit ║ 32-bit ║
╚════════╩═════════════╩═════════════╩═══════════════╩══════════════╝
1 Это может показаться очевидным, но это противоположно тому, как размеры операндов работают в 64-битном режиме: большинство по умолчанию - 32 бита, даже в 64-битном режиме, и префикс REX необходимо для их продвижения до 64 бит.
2Некоторые инструкции по умолчанию имеют размер 64-битного операнда без префикса REX
, особенно push
, pop
, call
и условные переходы, и, как указывает Питер ниже, это приводит к нечетной ситуации, когда по крайней мере некоторые из этих инструкций (push
и pop
включены) не могут быть закодированы для использования 32 -битные операнды, но могут использовать 16-битные операнды (с префиксом 0x66
).