Quiz Entry - updated: 2026.07.14
What are the special arithmetic operations for 128-bit results in x86-64?
Full multiply and divide treat %rdx:%rax as a single 128-bit value: mulq/imulq produce a 128-bit product there, and divq/idivq divide that 128-bit value, leaving quotient in %rax and remainder in %rdx.
When a 64×64 multiply could overflow 64 bits, or a division needs a 128-bit dividend, the architecture pairs two registers — %rdx holding the high half, %rax the low half.
| Instruction | Effect |
|---|---|
imulq S |
%rdx:%rax ← S × %rax (signed) |
mulq S |
%rdx:%rax ← S × %rax (unsigned) |
cqto |
%rdx:%rax ← sign-extend(%rax) |
idivq S |
%rax ← (%rdx:%rax) ÷ S, %rdx ← remainder (signed) |
divq S |
same, unsigned |
The dividend setup is the part you must not skip:
# signed x / y
movq x, %rax
cqto # sign-extend %rax across %rdx:%rax
idivq y # %rax = quotient, %rdx = remainder
# unsigned x / y
movq x, %rax
movq $0, %rdx # clear the high half
divq y
Warning: if %rdx holds leftover bits, the division uses a bogus 128-bit dividend; dividing by zero faults outright.
Go deeper:
Felix Cloutier — IMUL — signed multiply, including the full-width RDX:RAX form.
Felix Cloutier — DIV — the DIV side of the 128-bit RDX:RAX dividend setup.