IMUL
Signed Multiply
Instruction | Description |
---|---|
IMUL r/m8 | AX = AL * r/m8 |
IMUL r/m16 | DX:AX = AX * r/m16 |
IMUL r/m32 | EDX:EAX = EAX * r/m32 |
IMUL r/m64 | RDX:RAX = RAX * r/m64 |
IMUL r16, r/m16 | r16 = r16 * r/m16 |
IMUL r32, r/m32 | r32 = r32 * r/m32 |
IMUL r64, r/m64 | r64 = r64 * r/m64 |
IMUL r16, r/m16, imm16 * | r16 = r/m16 * imm16 |
IMUL r32, r/m32, imm32 * | r32 = r/m32 * imm32 |
IMUL r64, r/m64, imm32 * | r64 = r/m64 * imm32 |
IMUL r16, r/m16, imm8 * | r16 = r/m16 * sign-extended imm8 |
IMUL r32, r/m32, imm8 * | r32 = r/m32 * sign-extended imm8 |
IMUL r64, r/m64, imm8 * | r64 = r/m64 * sign-extended imm8 |
* If the first two operands are the same, the second one can be left out when using nasm
or .intel_syntax noprefix
.
Description
Performs a signed multiplication of two operands. This instruction has three forms, depending on the number of operands.
- One-operand form
This form is identical to that used by theMUL
instruction. Here, the source operand (in a general-purpose register or memory location) is multiplied by the value in theAL
,AX
,EAX
, orRAX
register (depending on the operand size) and the product (twice the size of the input operand) is stored in theAX
,DX:AX
,EDX:EAX
, orRDX:RAX
registers, respectively. - Two-operand form
With this form the destination operand (the first operand) is multiplied by the source operand (second operand). The destination operand is a general-purpose register and the source operand is an immediate value, a general-purpose register, or a memory location. The intermediate product (twice the size of the input operand) is truncated and stored in the destination operand location. - Three-operand form
This form requires a destination operand (the first operand) and two source operands (the second and the third operands). Here, the first source operand (which can be a general-purpose register or a memory location) is multiplied by the second source operand (an immediate value). The intermediate product (twice the size of the first source operand) is truncated and stored in the destination operand (a general-purpose register). When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.
The CF
and OF
flags are set when the signed integer value of the intermediate product differs from the sign-extended operand-size-truncated product, otherwise the CF
and OF
flags are cleared.
The three forms of the IMUL
instruction are similar in that the length of the product is calculated to twice the length of the operands. With the one-operand form, the product is stored exactly in the destination. With the two- and three- operand forms, however, the result is truncated to the length of the destination before it is stored in the destination register. Because of this truncation, the CF
or OF
flag should be tested to ensure that no significant bits are lost.
The two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the operands are signed or unsigned. The CF
and OF
flags, however, cannot be used to determine if the upper half of the result is non-zero.
In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R
prefix permits access to additional registers (R8
-R15
). Use of the REX.W
prefix promotes operation to 64 bits. Use of REX.W
modifies the three forms of the instruction as follows.
- One-operand form
The source operand (in a 64-bit general-purpose register or memory location) is multiplied by the value in theRAX
register and the product is stored in theRDX:RAX
registers. - Two-operand form
The source operand is promoted to 64 bits if it is a register or a memory location. The destination operand is promoted to 64 bits. - Three-operand form
The first source operand (either a register or a memory location) and destination operand are promoted to 64 bits. If the source operand is an immediate, it is sign-extended to 64 bits.
Operation
Single Operand
SRC
: operand
8-bit
TMP_XP = AL * SRC; // Signed multiplication
// TMP-XP is a signed integer at twice the width of the SRC
AX = TMP_XP[0..=15];
if SignExtend(TMP_XP[0..=7]) == TMP_XP {
CF = 0;
OF = 0;
} else {
CF = 1;
OF = 1;
}
16-bit
TMP_XP = AX * SRC; // Signed multiplication
// TMP_XP is a signed integer at twice the width of the SRC
DX:AX = TMP_XP[0..=31];
if SignExtend(TMP_XP[0..=15]) == TMP_XP {
CF = 0;
OF = 0;
} else {
CF = 1;
OF = 1;
}
32-bit
TMP_XP = EAX * SRC; // Signed multiplication
// TMP_XP is a signed integer at twice the width of the SRC
EDX:EAX = TMP_XP[0..=63];
if SignExtend(TMP_XP[0..=31]) == TMP_XP {
CF = 0;
OF = 0;
} else {
CF = 1;
OF = 1;
}
64-bit
TMP_XP = RAX * SRC; // Signed multiplication
// TMP_XP is a signed integer at twice the width of the SRC
RDX:RAX = TMP_XP[0..=127];
if SignExtend(TMP_XP[0..=63]) == TMP_XP {
CF = 0;
OF = 0;
} else {
CF = 1;
OF = 1;
}
Two Operands
DEST
: first operand
SRC
: second operand
TMP_XP = DEST * SRC // Signed multiplication
// TMP_XP is a signed integer at twice the width of the SRC
DEST = TruncateToOperandSize(TMP_XP);
if SignExtend(DEST) == TMP_XP {
CF = 0;
OF = 0;
} else {
CF = 1;
OF = 1;
}
Three Operands
DEST
: first operand
SRC1
: second operand
SRC2
: third operand
TMP_XP = SRC1 * SRC2 // Signed multiplication
// TMP_XP is a signed integer at twice the width of the SRC1
DEST = TruncateToOperandSize(TMP_XP);
if SignExtend(DEST) == TMP_XP {
CF = 0;
OF = 0;
} else {
CF = 1;
OF = 1;
}
Flags Affected
For the one operand form of the instruction, the CF
and OF
flags are set when significant bits are carried into the upper half of the result and cleared when the result fits exactly in the lower half of the result. For the two- and three-operand forms of the instruction, the CF
and OF
flags are set when the result must be truncated to fit in the destination operand size and cleared when the result fits exactly in the destination operand size. The SF
, ZF
, AF
, and PF
flags are undefined.