Повторяющиеся префиксы и обязательные префиксы в x86

В моем стремлении написать небольшой дизассемблер для Linux, специфичный для архитектуры x86, я столкнулся с небольшой проблемой. Это что касается обязательных префиксов и префиксов повтора. В документации Intel [1] сказано, что префиксы повторения - это 0xf2 или 0xf3, а обязательные префиксы - 0x66, 0xf2. или 0xf3.

Есть две инструкции, которые имеют следующие базовые коды операций:

crc32 - f2 0f 38 f0 (Здесь 0xf2 - обязательный префикс)
movbe - 0f 38 f0

Итак, коды операций инструкции movbe, которая должна повторяться, пока регистр счетчика не равен нулю, должны быть:

repnz movbe == f2 0f 38 f0

Когда я начинаю дизассемблировать инструкцию, если я вижу байт 0xf2, как мне узнать, что это обязательный префикс для инструкции crc32, но не префикс повтора для инструкции movbe или наоборот? С какой инструкцией сопоставить шаблон кода операции "f2 0f 38 f0"?

Что мне не хватает?

[1] http://www.intel.com/design/intarch/manuals/243191.HTM

С уважением и уважением,
Хришикеш Мурали


person Hrishikesh Murali    schedule 17.11.2011    source источник
comment
Что касается дизассемблеров x86, то тот, что включен в qemu хорошо читается. Он использует метод, предложенный @Karel для обработки префиксов.   -  person user786653    schedule 17.11.2011


Ответы (2)


Вы можете использовать префиксы повтора только со строковыми инструкциями (см. Руководство). «f2 0f 38 f0» всегда является командой CRC32.

person MazeGen    schedule 17.11.2011
comment
Да, я это пропустил. Спасибо! :-) - person Hrishikesh Murali; 17.11.2011
comment
Используйте ленивую оценку: не пытайтесь сразу понять значение префикса, просто сохраните его как необработанный префикс (т.е. просто помните, что у меня есть префикс 0xF2 вместо префикса REPNE, который также может быть обязательным префиксом). Когда у вас есть основной код операции, у вас есть контекст и вы можете правильно декодировать префиксы. - person MazeGen; 17.11.2011
comment
Да, похоже, простой способ обрабатывать префиксы. Спасибо за совет. - person Hrishikesh Murali; 17.11.2011

MOVBE, (переход к / от обратного порядка байтов в памяти), не является инструкцией, повторяемой через префикс REP((N)E).

Таким образом можно повторить только string instructions. Это: MOVS*, LODS*, STOS*, SCAS*, CMPS*, INS*, OUTS*, где * может быть B, W, D или Q (кроме INS * и OUTS *, которые подходят только к двойным словам, а не к четверным словам).

Ручной ввод Intel для _16 _ / _ 17_ объясняет это.

person Alexey Frunze    schedule 17.11.2011
comment
Ох, ладно. Так что тогда мне нужно провести специальную проверку в моем дизассемблере строковых инструкций. Спасибо, я этого не знал. - person Hrishikesh Murali; 17.11.2011
comment
Префикс +1 REPNE / REPNZ кодируется с помощью F2H. Префикс Repeat-Not-Zero применяется только к строкам и инструкциям ввода / вывода. (Из Тома 2А 2.1.1) - person user786653; 17.11.2011
comment
@HrishikeshMurali: да, имейте в виду, что 66h обычно является префиксом размера операнда, поэтому вам придется пройти аналогичную проверку и там. - person Alexey Frunze; 17.11.2011
comment
@Alex: Лучше было бы, как упомянул Карел Лейска ниже. Лучше оценивать префикс после того, как я встречу основной код операции, это упрощает работу. - person Hrishikesh Murali; 17.11.2011
comment
@HrishikeshMurali: верно. Фактически, это именно то, что я сделал некоторое время назад. - person Alexey Frunze; 17.11.2011