декодированная инструкция Intel XED не совсем соответствует коду сборки 8086 - PullRequest
0 голосов
/ 11 июня 2018

Я немного играю с xed, имея в виду написать небольшой эмулятор Intel 8086, и я хочу использовать xed в качестве декодера.Но когда я пишу небольшой код в asm (скомпилированный с nasm):

[CPU 8086]

mov al, 0x7F
xor bx, bx
xchg bx, bx

cli
hlt

и пытаюсь отобразить некоторые вещи, чтобы увидеть, если вы понимаете, как работает xed, я имею следующее поведение:

0x0:0x0 (0x0)
MOV : length = 2
operand0: AL (REG0)
operand1: 7f (IMM0)

0x0:0x2 (0x2)
XOR : length = 3
operand0: BX (REG0)
operand1: BX (REG1)
operand2: (REG2)

0x0:0x5 (0x5)
XCHG : length = 3
operand0: BX (REG0)
operand1: BX (REG1)

0x0:0x8 (0x8)
CLI : length = 1
operand0: EFLAGS (REG0)

0x0:0x9 (0x9)
HLT : length = 1

Я не понимаю, почему у меня есть 3 операнда для xor и 1 операнд для cli, и, как правило, во многих случаях отображаемые операнды не соответствуют числу операндов, указанных в intel.Что я делаю не так?

Есть код, который я использовал в gist (я приложил все усилия, чтобы сделать его как можно более минимальным)


[edit]

Теперь все немного яснее: я скомпилировал xor bx, bx с nasm -f bin test.s, и моя программа выдала мне:

0x0:0x0 (0x0)
XOR : length = 2
operand0: BX (REG0)
operand1: BX (REG1)
operand2: FLAGS (REG2)

Длина xor равна 2: этоХорошо, мы в режиме 16 бит.Есть 2 явных операнда: bx и bx, вот так. Есть один неявный подавленный операнд: флаги (как сказал @Peter Corde)

Теперь все выглядит хорошо

1 Ответ

0 голосов
/ 11 июня 2018

CLI очищает бит IF в EFLAGS, так что это имеет смысл.

Похоже, что XED включает в себя неявные операнды, а не только те, которые явно указаны в машинном коде.т.е. все изменения в архитектурном состоянии.

XOR записывает флаги, а XCHG - нет.Таким образом, REG2, вероятно, EFLAGS.Но ваш код содержит только case XED_OPERAND_REG0 и ...REG1 в выражении switch, поэтому, вероятно, у него есть имя (возможно, EFLAGS), но ваш код решил не печатать его.


Мне было любопытнопоэтому я прочитал для вас документы по XED: XED классифицирует операнды в соответствии с их видимостью: либо явные (например, bx в xor bx,bx), либо неявные, либо "IMPLICIT SUPPRESSED (SUPP)".Операнды SUPP:

Операнды SUPP:

  • не используются при выборе кодировки, (это отличие от неявного простого)
  • не распечатывается при разборке,
  • не представляется с использованием битов операндов в кодировке.

Таким образом, вы должны проверить xed_operand_visibility_enum_t и распечатать только явные операнды.


Кстати, вы, кажется, собрали свой код в 32-битном или 64-битном режиме, потому что ваши 16-битные инструкции, такие как xor bx,bx, имеют длину 3 байта.В 16-битном режиме это был бы просто код операции + modrm.Префикс размера операнда (66), добавленный ассемблером (и правильно декодированный дизассемблером), объяснит это.

[CPU 8086] не означает [BITS 16].Если по какой-то причине вам действительно не нужен 16-битный режим, вам, вероятно, следует продолжать использовать 32-битный режим.(Ваш дизассемблер уже декодировал его в том же режиме, для которого собирал ассемблер. Использование BITS 16 позволит вам поместить 16-битный машинный код в 32-битный объектный файл, что приведет к неправильному декодированию.

...