TransWikia.com

x86-16 imul instruction "wrong parameters"?

Stack Overflow Asked by vbvbvb123 on January 30, 2021

So, I have code like this :

    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:

I don’t know, in 16-bit register IMUL instruction give me an error like this in emu8086.

It should be fine if use 32-bit register like IMUL EAX, 34 (not in emu8086).

How I can fix this ?

One Answer

The immediate form of the IMUL instruction, opcodes 6B and 69, actually takes three operands, all of the same size (here 16 bits): IMUL r, r/m, imm. It multiplies the second operand by the third and places the result in the first, truncating in case of overflow. This form was not supported by the original 8086, but was added as an extension in the 80186, circa 1982, and has been supported by all newer x86 processors.

Your 32-bit assembler apparently supports IMUL EAX, 34 as syntactic sugar for IMUL EAX, EAX, 34, with EAX used as both a source and destination operand.

So there are three possibilities here; I don't know anything about emu8086 so am not sure which one applies.

  • Perhaps your emu8086 emulator/assembler does support 186 instructions, but not the syntactic sugar. In this case you simply need to write IMUL AX, AX, 34.

  • Perhaps emu8086 is currently set to support only the original 8086 instruction set, but has some option to add the 186 extensions. In that case, once you enable that option, you should be able to use your desired instruction, possibly with the three-operand syntax listed above.

  • Or perhaps emu8086, as its name suggests, only supports the 8086 instruction set, period. In that case you have to rewrite your code to use the one-operand form IMUL r/m, and load your constant 34 into a register (or place it in memory). Note that IMUL r/m is widening and will place its 32-bit result into DX:AX, so your zero value in DX will be clobbered if the result is negative or larger than 32767; you'll need to adapt your code accordingly.

    Or rewrite it with shifts and adds which may be more efficient anyway: x * 34 == (x << 5) + (x << 1). Or, of course, you can find another emulator that does support 186 instructions.

Answered by Nate Eldredge on January 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP