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 :/
The IMUL instruction takes one, two or three operands. It can be used for byte, word or dword operation. IMUL only works with signed numbers. The result is the correct sign to suit the signs of the multiplicand and the multiplier.
The MUL instruction multiplies unsigned numbers. IMUL multiplies signed numbers. For both instructions, one factor must be in the accumulator register (AL for 8-bit numbers, AX for 16-bit numbers, EAX for 32-bit numbers). The other factor can be in any single register or memory operand.
Each assembly language statement is split into an opcode and an operand . The opcode is the instruction that is executed by the CPU and the operand is the data or memory location used to execute that instruction.
An x86 instruction can have zero to three operands. Operands are separated by commas (,) (ASCII 0x2C). For instructions with two operands, the first (lefthand) operand is the source operand, and the second (righthand) operand is the destination operand (that is, source->destination).
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With