【问题标题】:intel xed decoded instruction doesn't perfectly match the 8086 assembly codeintel xed 解码指令与 8086 汇编代码不完全匹配
【发布时间】:2018-06-11 20:34:14
【问题描述】:

我正在玩一点 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

我不明白为什么我有 3 个用于 xor 的操作数和 1 个用于 cli 的操作数,而且通常情况下,显示的操作数与 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 所说)

现在一切都很好

【问题讨论】:

    标签: x86 intel disassembly machine-code xed


    【解决方案1】:

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

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

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


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

    SUPP 操作数是:

    • 不用于选择编码,(这是与普通隐式的区别)
    • 反汇编时不打印,
    • 在编码中不使用操作数位表示。

    所以你应该检查xed_operand_visibility_enum_t 并且只打印显式操作数。


    顺便说一句,您似乎已经在 32 位或 64 位模式下组装了代码,因为像 xor bx,bx 这样的 16 位指令是 3 个字节长。在 16 位模式下,它只是 opcode + modrm。由汇编器添加(并由反汇编器正确解码)的操作数大小前缀 (66) 可以解释它。

    [CPU 8086] 不代表[BITS 16]。除非出于某种原因您真的想要 16 位模式,否则您应该继续使用 32 位模式。 (您的反汇编程序已经在以与您的汇编程序汇编相同的模式对其进行解码。使用BITS 16 可以让您将 16 位机器代码放入 32 位目标文件中,这只会使其解码错误。

    【讨论】:

    • 当我在我的 asm 文件中使用 [BIT 32] 而不是 [CPU 8086] 时,我得到相同的结果
    • @Adrien:当然可以。 xor bx,bx 在 32 位模式中需要 66 前缀,但在 BITS 16不需要。我猜你的汇编程序设置[CPU 8086] 不会设置[BITS 16]。无论如何,您可能不想要BITS 16,除非您的目标文件格式可以代表它。将 16 位机器代码放在 32 位目标文件中只会使其解码错误。 (例如xor ebx,ebx
    • @Adrien 关于 XOR,EFALGS 寄存器对应于 XED_OPERAND_REG2,您的代码不会在 switch 语句中打印。所以你最终只打印了(REG2) 部分。
    • @PeterCordes 我正在创建原始二进制文件格式。这个项目是为了在学校做一次演讲,所以也许我应该尝试一些更简单的事情,因为我理解我的问题是我尝试使用 386+ 的规则对英特尔 8086 的指令进行编码?
    • @HadiBrais 我知道,但问题是 xor 应该只有 2 个操作数,而不是 3 个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2017-07-24
    • 1970-01-01
    相关资源
    最近更新 更多