Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 911
Joshua Enfield Avatar asked Sep 29 '10 04:09

Joshua Enfield


People also ask

What does Imul do in assembly?

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.

What is the difference between MUL and Imul instruction?

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.

What are Assembly operands?

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.

How many operands does the x86 add assembly instruction have?

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


1 Answers

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.

like image 117
Chris Taylor Avatar answered Sep 21 '22 16:09

Chris Taylor