Search code examples
assemblyx86multiplication

imul assembly instruction - one operand?


I am using a run-time debugger.

EAX: 0000 0023 EDX: 5555 5556

imul edx

EAX: aaaa aac2 EDX: 0000 000b

I am utterly confused, and can't figure out how this multiply is working. What's happening here? I notice in a similar question here that imul ebx ; result in EDX:EAX I don't understand the EDX:EAX notation though :/


Solution

  • When the one-operand form of imul is passed a 32 bit argument, it effectively means EAX * src where both EAX and the source operand are 32-bit registers or memory.

    The product of two 32 bit values doesn't necessarily fit in 32 bits: the full multiply result can take up to 64 bits. The high 32 bits of the answer will be written to the EDX register and the low 32 bits to the EAX register; this is represented with the EDX:EAX notation.

    In your case with imul edx, you get EDX:EAX = EAX * EDX. It's fine for the explicit source operand to be one of the implicit operands, even EAX to square into EDX:EAX.


    If you only want the low 32 bits of the result, use the 2-operand form of imul; it runs faster and doesn't have any implicit operands (so you can use whatever registers are most convenient).

    imul ecx, esi does ecx *= esi like you'd expect, without touching EAX or EDX. It's like C where unsigned x=...; x *= y; has the same width for the result as the inputs.

    imul also has an immediate form: imul ecx, ebx, 1234 does ecx = ebx * 1234. Many assemblers will accept imul ecx, 1234 as short-hand for imul ecx, ecx, 1234.


    These 32x32 => 32-bit forms of imul work correctly for signed or unsigned; the results of one-operand mul and imul only differ in the upper half (in EDX), not the low-half EAX output.

    See Intel's instruction reference manual entry for imul.