assembly - 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, DX
MOV BX, [SP]
LOOP .LOOP
.EXIT_LOOP:
我不知道,在 16 位寄存器IMUL
指令中,emu8086 中会出现这样的错误。
如果使用 32 位寄存器IMUL EAX, 34
(不在 emu8086 中)应该没问题。
我该如何解决这个问题?
解决方案
IMUL
指令、操作码6B
和的立即数形式69
实际上采用三个操作数,它们的大小都相同(此处为 16 位):IMUL r, r/m, imm
. 它将第二个操作数乘以第三个并将结果放在第一个操作数中,在溢出的情况下截断。最初的 8086 不支持这种形式,但在80186中作为扩展添加,大约在 1982 年,并且已被所有较新的 x86 处理器支持。
您的 32 位汇编器显然支持将EAX 用作源操作数和目标操作数的IMUL EAX, 34
语法糖。IMUL EAX, EAX, 34
所以这里有三种可能性;我对emu8086一无所知,所以不确定哪个适用。
也许您的 emu8086 仿真器/汇编器确实支持 186 条指令,但不支持语法糖。在这种情况下,您只需要编写
IMUL AX, AX, 34
.或许 emu8086 当前设置为仅支持原始 8086 指令集,但有一些选项可以添加 186 扩展。在这种情况下,一旦启用该选项,您应该能够使用所需的指令,可能使用上面列出的三操作数语法。
或者也许emu8086,顾名思义,只支持8086指令集,句号。在这种情况下,您必须重写代码以使用单操作数形式
IMUL r/m
,并将常量 34 加载到寄存器中(或将其放在内存中)。请注意,它IMUL r/m
正在扩大并将其 32 位结果放入中,因此如果结果为负数或大于 32767,则DX:AX
您的零值将被破坏;DX
您需要相应地调整您的代码。或者用 shift 和 add 重写它,这可能更有效:
x * 34 == (x << 5) + (x << 1)
. 或者,当然,您可以找到另一个支持 186 条指令的仿真器。
推荐阅读
- sql-server - 在 CASE 语句中使用两个 = 符号?
- mysql - 查询说明
- html - 如何使用引导程序将大于其容器的段落元素居中?
- python - 尝试使用 subprocess.check_output python 解释器使此代码不可知
- reactjs - 使用 React JS 在 firebase 中查询子集合的子集合
- mesh - 虚幻引擎中的静态网格物体和骨架网格物体之间有共同的父节点吗?
- django - .env 在 uwsgi 上使用 django-environ 重新加载
- java - SQLite rawQuery + String.format = "该语句有 0 个参数。"?
- python-3.x - Web Scraper 未撤回所有 URL
- php - Google auth - 有什么方法可以在重定向 URL 中发回自定义数据?