问题描述
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的直接形式,即操作码6B
和69
,实际上需要三个操作数,它们的大小均相同(此处为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条指令的仿真器。