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
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.