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 :/
When the one-operand form of
imulis passed a 32 bit argument, it effectively meansEAX * srcwhere bothEAXand 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
EDXregister and the low 32 bits to theEAXregister; this is represented with theEDX:EAXnotation.In your case with
imul edx, you getEDX:EAX = EAX * EDX. It’s fine for the explicit source operand to be one of the implicit operands, evenEAXto square intoEDX: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, esidoesecx *= esilike you’d expect, without touchingEAXorEDX. It’s like C whereunsigned x=...;x *= y;has the same width for the result as the inputs.imulalso has an immediate form:imul ecx, ebx, 1234doesecx = ebx * 1234. Many assemblers will acceptimul ecx, 1234as short-hand forimul ecx, ecx, 1234.These 32×32 => 32-bit forms of
imulwork correctly for signed or unsigned; the results of one-operandmulandimulonly differ in the upper half (inEDX), not the low-halfEAXoutput.See Intel’s instruction reference manual entry for
imul.