idiv
Signed Divide
Signed divide (AX / src).
Pseudocode Operation
if (src == 0) raise #DE;
temp_dividend = (src_size == 8) ? AX : ((src_size == 16) ? (DX:AX) : ((src_size == 32) ? (EDX:EAX) : (RDX:RAX)));
if ((temp_dividend / src) > max_signed || (temp_dividend / src) < min_signed) raise #DE;
quotient = temp_dividend / src;
remainder = temp_dividend % src;
if (src_size == 8) { AL ← quotient; AH ← remainder; }
else if (src_size == 16) { AX ← quotient; DX ← remainder; }
else if (src_size == 32) { EAX ← quotient; EDX ← remainder; }
else { RAX ← quotient; RDX ← remainder; }
OF ← undefined; SF ← undefined; ZF ← undefined; AF ← undefined; CF ← undefined; PF ← undefined;
Example
Encoding
Operands
-
dest
Register or memory operand
Related
Across architectures
Integer Divide : how x86, ARM, RISC-V, and PowerISA each do this.
More in Base
Reference
Instruction Forms
| Opcode | Instruction | Op/En | 64/32-bit Mode | CPUID | Description |
|---|---|---|---|---|---|
| F6 /7 | IDIV r/m8 | M | Valid Valid | Signed divide AX by r/m8, with result stored in: AL := Quotient, AH := Remainder. | |
| F7 /7 | IDIV r/m16 | M | Valid Valid | Signed divide DX:AX by r/m16, with result stored in AX := Quotient, DX := Remainder. | |
| F7 /7 | IDIV r/m32 | M | Valid Valid | Signed divide EDX:EAX by r/m32, with result stored in EAX := Quotient, EDX := Remainder. | |
| REX.W + F7 /7 | IDIV r/m64 | M | Valid N.E. | Signed divide RDX:RAX by r/m64, with result stored in RAX := Quotient, RDX := Remainder. |
Description
Divides the (signed) value in the AX, DX:AX, or EDX:EAX (dividend) by the source operand (divisor) and stores the result in the AX (AH:AL), DX:AX, or EDX:EAX registers. The source operand can be a general-purpose register or a memory location. The action of this instruction depends on the operand size (dividend/divisor). Non-integral results are truncated (chopped) towards 0. The remainder is always less than the divisor in magnitude. Overflow is indicated with the #DE (divide error) exception rather than with the CF flag. 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. In 64-bit mode when REX.W is applied, the instruction divides the signed value in RDX:RAX by the source operand. RAX contains a 64-bit quotient; RDX contains a 64-bit remainder. See the summary chart at the beginning of this section for encoding data and limits. See Table 3-53. Table 3-53. IDIV Results
Operand Size Dividend Divisor Quotient Remainder Quotient Range Word/byte AX r/m8 AL AH -128 to +127 Doubleword/word DX:AX r/m16 AX DX -32,768 to +32,767 Quadword/doubleword EDX:EAX r/m32 EAX EDX -231 to 231 - 1 Doublequadword/ quadword RDX:RAX r/m64 RAX RDX -263 to 263 - 1
Operation
IF SRC = 0 THEN #DE; (* Divide error *) FI; IF OperandSize = 8 (* Word/byte operation *) THEN temp := AX / SRC; (* Signed division *) IF (temp > 7FH) or (temp < 80H) (* If a positive result is greater than 7FH or a negative result is less than 80H *) THEN #DE; (* Divide error *) ELSE AL := temp; AH := AX SignedModulus SRC; FI; ELSE IF OperandSize = 16 (* Doubleword/word operation *) THEN temp := DX:AX / SRC; (* Signed division *) IF (temp > 7FFFH) or (temp < 8000H) (* If a positive result is greater than 7FFFH or a negative result is less than 8000H *) THEN #DE; (* Divide error *) ELSE AX := temp; DX := DX:AX SignedModulus SRC; FI; FI; ELSE IF OperandSize = 32 (* Quadword/doubleword operation *) temp := EDX:EAX / SRC; (* Signed division *) IF (temp > 7FFFFFFFH) or (temp < 80000000H) (* If a positive result is greater than 7FFFFFFFH or a negative result is less than 80000000H *) THEN #DE; (* Divide error *) ELSE EAX := temp; EDX := EDXE:AX SignedModulus SRC; FI; FI; ELSE IF OperandSize = 64 (* Doublequadword/quadword operation *) temp := RDX:RAX / SRC; (* Signed division *) IF (temp > 7FFFFFFFFFFFFFFFH) or (temp < 8000000000000000H) (* If a positive result is greater than 7FFFFFFFFFFFFFFFH or a negative result is less than 8000000000000000H *) THEN #DE; (* Divide error *) ELSE RAX := temp; RDX := RDE:RAX SignedModulus SRC; FI; FI; FI;