imul assembly instruction - one operand?

Joshua Enfield picture Joshua Enfield · Sep 29, 2010 · Viewed 36k times · Source

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 :/

Answer

Chris Taylor picture Chris Taylor · Sep 29, 2010

When the one-operand form of imul is passed a 32 bit argument (as in your case with EDX) it effectively means EAX * EDX where both EAX and EDX are 32 bit registers.

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.


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.