Изучая x64, я изо всех сил пытался понять некоторые обозначения в руководстве Intel.
Давайте посмотрим 0xC7
MOV
:
О /0
../7
там написано:
Исторически в этом документе указывалось только поле ModR/M.reg. ограничения с обозначением /0.../7 так и не указал ограничения на поля ModR/M.mod и ModR/M.r/m в кодировке коробки.
Мои вопросы:
/0
— это код ограничения, но какое ограничение? Что это означает при интерпретации инструкции?c7c701020304...
Как узнать, нужно ли мне готовить imm16(0102
или imm32(01020304
)? Путем тестирования я знаю это в этом imm32
, но не понимаю почему. Я делаю вывод, что это связано с рекс+модрм.{ xxd --ps -r | ndisasm -b64 -; } <<<c7c701020304
00000000 C7C701020304 mov edi,0x4030201
ndisasm
анализирует это как imm32
вместо imm16
?/digit
по-прежнему ограничивает только поле ModRM.reg. Это означает, что нужно поместить любую цифру после косой черты в поле reg байта ModRM.
Это примечание касается новых инструкций Intel AMX, некоторые из которых имеют другую спецификацию ModRM. Например, TDPBSSD/TDPBSUD/TDPBUSD/TDPBUU требуют mod=11 (другими словами, они не могут иметь операнд в памяти).
А TILELOADD/TILELOADDT1 требуют mod!=11 и rm=100 (у них должен быть операнд памяти, и он должен быть закодирован с помощью SIB)
@ton: Как читать нотацию Intel Opcode объясняет некоторые обозначения, например, «ib» означает 1 непосредственный байт, iw означает 2 байта и т. д.
@PeterCordes Я это понял, но это не объясняет мой вопрос. «Почему ndisasm анализирует c7c701020304
как imm32 вместо imm16?»
Я думаю, это означает что-то вроде imm16 в реальном режиме (16 бит); и imm32 в других режимах; но в этой таблице, кажется, ничего об этом не говорится.
@ton: Я уверен, что на этом сайте уже есть ответ, но я его еще не нашел. Но да, вы правы: 16-бит в 16-битном режиме (реал или вм86), 32-бит в остальных режимах. Префикс размера операнда (66h) поменяет это место, сделав его 32-битным в 16-битном режиме и наоборот. Поскольку вы указали -b 64
для ndisasm, он предполагает, что этот код будет запускаться в 64-битном режиме, и в этом случае непосредственный код действительно будет 32-битным. Используйте -b 16
и вы увидите другой вариант.
@NateEldredge «16 бит в 16-битном режиме (реальном или vm86)». Бит D также может быть сброшен для 16-битного CS в защищенном режиме, и в этом случае размер операнда по умолчанию также составляет 16 бит.
Ох... "только указал ограничения поля ModR/M.reg с обозначением /0 ... /7"... понял... мне было трудно интерпретировать это, прежде чем вы сказали, введите любую цифру после косой черты в поле reg байта ModRM. Спасибо... Но я так и не могу понять, как интерпретировать непосредственный размер