Повторете префиксите и задължителните префикси в x86

В стремежа си да напиша малък дизасемблер за Linux, специфичен за x86 arch, се сблъсках с малък проблем. Това е по отношение на задължителните префикси и повтарящите се префикси. Разглеждайки документите на 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, (преместване към/от big-endian в паметта), не е инструкция, която може да се повтори през префикс REP((N)E).

Само string instructions са повторими по този начин. Това са: MOVS*, LODS*, STOS*, SCAS*, CMPS*, INS*, OUTS*, където * е едно от B, W, D или Q (с изключение на INS* и OUTS*, които достигат само до двойни думи, а не до четири думи).

Ръчното въвеждане на Intel за rep/rep(n)e обяснява това.

person Alexey Frunze    schedule 17.11.2011
comment
А, добре. Така че тогава трябва да имам специална проверка в моя дизасемблер за инструкции за низове. Благодаря, не знаех това. - person Hrishikesh Murali; 17.11.2011
comment
Префиксът +1 REPNE/REPNZ е кодиран с помощта на F2H. Префиксът Repeat-Not-Zero се прилага само за низове и инструкции за въвеждане/извеждане. (От том 2A 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