intel xed 解码指令与 8086 汇编代码不完全匹配

intel xed decoded instruction doesn't perfectly match the 8086 assembly code

我正在玩 xed,目的是编写一个英特尔 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

我不明白为什么我的xor有3个操作数,cli有1个操作数,而且一般情况下显示的操作数与intel指定的操作数不匹配的情况很多。我做错了什么?

有我在gist中使用的代码(我已尽力使其尽可能少)


[编辑]

现在事情更清楚了:我用 nasm -f bin test.s 编译了 xor bx, bx,我的程序给了我:

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

xor 的长度是 2 :没错,我们是在 16 位模式下。 有 2 个显式操作数:bx 和 bx 没错 有一个隐式抑制操作数:标志(如@Peter Corde 所说)

现在一切看起来都很好

CLI 清除 EFLAGS 中的 IF 位,所以这是有道理的。

看起来 XED 包括隐式操作数,而不仅仅是机器代码中显式的操作数。即对架构状态的所有更改。

XOR 写标志,但 XCHG 不写。所以 REG2 可能是 EFLAGS。但是您的代码在 switch 语句中只有 case XED_OPERAND_REG0...REG1,所以它可能有一个名称(可能是 EFLAGS)但您的代码选择不打印它。


我很好奇,所以我为您阅读了 XED 文档:XED classifies operands 根据它们的可见性:显式(如 xor bx,bx 中的 bx)或隐式,或 "IMPLICIT SUPPRESSED (SUPP)"。 SUPP 操作数是:

SUPP operands are:

  • not used in picking an encoding, (this is the difference from plain implicit)
  • not printed in disassembly,
  • not represented using operand bits in the encoding.

所以你应该检查 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 位目标文件中,这只会使其解码错误。