Понимание операндов x86 m* (FPU и других)

Я пытаюсь сделать простой дизассемблер x86 (пока 32-битный) для учебных целей.

Таким образом, документы Intel идут:

введите описание изображения здесь

Но я нахожу это очень запутанным.

Прежде всего, операнды m8-32, кажется, указывают либо ES:(E)DI или же DS:(E)SI,
Но нельзя сказать, в каких ситуациях будет та или иная ситуация. В некоторых кодах операций у вас есть OPCODE m8, m8в других у вас есть только один операнд m8и после проверки нескольких, я пришел к выводу, что нет общего правила.

Тогда есть эти другие, которые просто описаны как memory operand in memory, которые оставляют меня еще более запутанным. Должно ли быть смещение, может быть, абсолютный адрес или относительное смещение? Если так, то какой смысл, так как у нас есть moffs а также rel?

Последующие имеют смысл, но является ли число после двоеточия смещением?
А амперсанды оставляют меня совершенно невежественным.

Кроме того, есть эти m[number][descriptor]Что, насколько я вижу, для FPU? (Я еще не имел дело с экранированными кодами 0Fh).

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Прошу прощения за то, что я, вероятно, упускаю что-то действительно очевидное, как я часто это делаю.

Заранее спасибо.

2 ответа

Нормальные инструкции вроде add который может использовать операнд памяти, также работать с регистрами, поэтому ADD имеет кодировки для add r32, r/m32 а также add r/m32, r32,add eax, ecxможет использовать любую кодировку / код операции (не имеет значения).

Вот почему m32(и неr/m32) обычно является неявным операндом дляmovsd или же stosd или другие строковые инструкции, и почему Intel говорит, что они обычно используют ES:(E)DI или же DS:(E)SI,

Прежде всего, операнды m8-32, кажется, указывают либо ES:(E)DI, либо DS:(E)SI. Но нельзя сказать, в каких ситуациях будет та или иная ситуация.

m32 означает 32-битный операнд памяти, который не может быть регистром. Посмотрите на записи для конкретных инструкций, чтобы увидеть, как определены операнды(например, DS:(E/R)SI подразумевается дляlodsb/w/d/q), в то время как другие могут использовать операнд ModR/M, но для этого требуется память.

Для x87 дополнительная аннотация говорит вам, как инструкция интерпретирует это. например m32fp 32-битная IEEE с одинарной точностью float (например, для fmul или же fld), в то время как m32int 32-разрядное целое число (например, для fimul или же fild).


Помимо x87, число просто говорит вам размер операнда. Это все.

Обычно операнды памяти задаются с помощью обычного ModR/M + необязательного SIB. Единственными исключениями являются неявные режимы адресации (например, pop rax чтение qword [rsp]или строковые инструкции), или moffs формы MOV, которые пропускают байт ModR/M и просто используют 16/32/64-битное смещение (тот же размер, что и размер адреса).

mov al/ax/eax/rax, [moffs8/16/32/64] (или форма для хранения) - единственная инструкция, которая может использовать 64-битный абсолютный адрес напрямую, без предварительного внесения в регистр.

Обратите внимание, что moffs8 является 8-битным операндом, а не 8-битным непосредственным адресом. Атрибут адреса-размера инструкции (по умолчанию 64-битный в 64-битном режиме, переопределяемый с помощью 0x67 префикс размера адреса) определяет, сколько байтов абсолютного адреса следует за кодом операции.

Ассемблер позаботится об этом за вас и использует moffs кодирование, когда он сохраняет размер кода для mov eax, [symbol] в 32-битном коде. В общем, просто напишите режимы адресации обычным способом ( ссылка на содержимое области памяти. (Режимы адресации x86)) и позвольте ассемблеру сгенерировать байты ModR/M или предупредить вас, если вы сделаете что-то недопустимое (не кодируемое), например попытайтесь использование movsb с разными регистрами.


Подробнее о x86 asm см. Вики-тег x86. Кроме того, руководства Агнера Фога очень хороши, хотя он не пытается охватить основные вещи, как это. Однако, прочитав руководства Агнера и увидев, что он говорит о своих коротких примерах (пара инструкций), вы сможете понять, как работает asm.

Я только что обнаружил, что у http://ref.x86asm.net/ есть " выродочная " версия его таблиц.

Опкоды описаны здесь.

Компьютерная версия не так однозначна, как кодер.

Тем не менее, если бы кто-то мог направить меня туда, где он сам узнает это, это было бы очень ценно. Кажется, я не могу найти его в документации Intel или где-либо еще, кроме x86asm.

Опять же, я часто скучаю по вещам, поэтому, если я найду что-то, я буду редактировать.

Надеюсь, я смогу помочь.

Другие вопросы по тегам