【问题标题】:x86-16 imul instruction "wrong parameters"?x86-16 imul 指令“参数错误”?
【发布时间】:2020-10-16 13:37:45
【问题描述】:

所以,我有这样的代码:

    XOR DX, DX
    MOV BX, 1
    MOV AX, BX
    MOV CX, 10
.LOOP:
    JCXZ .EXIT_LOOP
    IMUL AX, 34     ; in here
    SUB AX, DX
    ADD AX, 2
    PUSH AX
    INC DX
    DEC DX
    XCHG BX, DX
    MOV BX, [SP]
    LOOP .LOOP
.EXIT_LOOP:

我不知道,在 16 位寄存器 IMUL 指令中给我一个类似 this in emu8086 的错误。

如果使用像IMUL EAX, 34这样的32位寄存器应该没问题(不是在emu8086中)。

我该如何解决这个问题?

【问题讨论】:

  • 立即形式的 imul 指令需要三个操作数,因此您可以尝试编写 IMUL AX, AX, 34。我不知道为什么两个操作数适用于 32 位格式而不适用于 16 位格式;可能是emu8086 的汇编程序中的一个错误。我没有在这里安装它,所以我无法测试它。另一种可能性是您处于模拟真正 8086 的模式,在该模式下不存在 IMUL 的直接形式;我相信它是在 80186 中引入的。当您编写 32 位格式时,您显然是在假设 80386 或更高版本,这将支持直接格式。
  • @NateEldredge 哎呀...查看我的编辑
  • 好的,那么你必须弄清楚emu8086在模拟什么。如果它是 80186 或更高版本,则该指令应该存在,您可以使用 IMUL AX, AX, 34 组装它。如果是 8086,那么您没有立即乘法指令,您将不得不使用单操作数 r/m 形式,首先将 34 加载到寄存器中。请注意,单操作数形式正在扩大,并将用结果的高半部分覆盖 DX。
  • 相关:Is it possible to multiply by an immediate with mul in x86 Assembly? - 现在的答案提到 imul-immediate 需要 186,但不是真正的重复。同样What's 'new' in a 'new' processor when viewed from programmer's pointimul 为例。

标签: assembly x86-16 emu8086


【解决方案1】:

IMUL instruction 的直接形式,操作码 6B69,实际上采用三个相同大小的操作数(此处为 16 位):IMUL r, r/m, imm。它将第二个操作数乘以第三个并将结果放在第一个操作数中,在溢出的情况下截断。最初的 8086 不支持这种形式,但大约在 1982 年,作为扩展添加到 80186 中,并且已被所有较新的 x86 处理器支持。

您的 32 位汇编器显然支持 IMUL EAX, 34 作为 IMUL EAX, EAX, 34 的语法糖,并将 EAX 用作源操作数和目标操作数。

所以这里有三种可能性;我对emu8086一无所知,所以不确定哪个适用。

  • 也许您的 emu8086 仿真器/汇编器确实支持 186 条指令,但不支持语法糖。在这种情况下,您只需要写IMUL AX, AX, 34

  • 也许emu8086当前设置为仅支持原始8086指令集,但有一些选项可以添加186扩展。在这种情况下,一旦启用该选项,您应该能够使用所需的指令,可能使用上面列出的三操作数语法。

  • 或者也许emu8086,顾名思义,只支持8086指令集,句号。在这种情况下,您必须重写代码以使用单操作数形式IMUL r/m,并将常量 34 加载到寄存器中(或将其放入内存中)。请注意,IMUL r/m 正在扩大,并将其 32 位结果放入DX:AX,因此如果结果为负数或大于 32767,DX 中的零值将被破坏;您需要相应地调整您的代码。

    或者用 shift 和 add 重写它,这可能更有效:x * 34 == (x << 5) + (x << 1)。或者,当然,您可以找到另一个支持 186 条指令的模拟器。

【讨论】:

  • EMU8086 模拟 8086,但它确实支持一些 80186。它支持 pusha/popa 并立即推送。位移指令支持 1 以外的立即数,但它们被转换为多个 1 位操作。所以 shl ax, 4 将是 4 shl ax, 1 。它只支持 IMUL 的一种操作数形式。所以它大于 8086 小于 80186
  • @MichaelPetch:很有趣,也很奇怪。
  • @NateEldredge:它也有令人困惑的行为,比如让mov [si], 1234himply word operand size;我不会向任何人推荐它,尤其是学习 asm。 (虽然主要是因为它是一个 DOS / 8086 模拟器,这已经是开始学习 asm 的一种糟糕方式,IMO。)但我似乎还记得其他一些设计不良的行为实例,以及可能无用的错误消息(我忘记了),它们有在过去的 x86 问题中提出 emu8086。总体意见 = 低。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多