微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

x86-16 imul指令“参数错误”?

如何解决x86-16 imul指令“参数错误”?

所以,我有这样的代码

    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,[SP]
    LOOP .LOOP
.EXIT_LOOP:

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

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

我该如何解决

解决方法

IMUL instruction的直接形式,即操作码6B69,实际上需要三个操作数,它们的大小均相同(此处为16位):IMUL r,r/m,imm。它将第二个操作数乘以第三个操作数,并将结果放在第一个操作数中,以防溢出时截断。最初的8086不支持这种格式,但是在80186中作为扩展名在1982年左右添加了该格式,并且所有较新的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中的零值将被破坏。您需要相应地修改代码。

    或者通过移位和添加来重写它,无论如何它们都可能更有效:x * 34 == (x << 5) + (x << 1)。或者,当然,您可以找到另一个支持186条指令的仿真器。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。