Modulo in x86-64 Assembly
The modulus operation (a % b
) can be computed in two ways:
1. General Modulo (any divisor)
Use div
(unsigned) or idiv
(signed). The remainder is always placed in the high register (rdx
in 64-bit mode).
Syntax (unsigned)
mov rax, dividend ; low half of dividend
xor rdx, rdx ; clear high half
div divisor ; (RDX:RAX) ÷ divisor
mov rax, rdx ; rax = remainder
Example
; rax = rdi % rsi
mov rax, rdi
xor rdx, rdx
div rsi
mov rax, rdx
2. Modulo When Divisor is a Power of Two
If the divisor is a power of two (2ⁿ), the remainder is just the lowest n bits of the dividend. No divide instruction is needed.
% 2⁸ = % 256
→ keep the lowest 8 bits.% 2¹⁶ = % 65536
→ keep the lowest 16 bits.% 2³²
→ keep the lowest 32 bits.
These bits are directly accessible through the sub-registers.
Syntax
xor rax, rax
mov al, dil ; rax = rdi % 256
xor rbx, rbx
mov bx, si ; rbx = rsi % 65536
Why This Works
-
Dividing by
2ⁿ
is the same as shifting rightn
bits. -
The remainder is whatever’s left in the low
n
bits after shifting. -
Example:
0x1234ABCD % 256 = 0xCD 0x1234ABCD % 65536 = 0xABCD
Quick Reference Table (Power of Two Modulo)
Modulo (divisor) | Keep low bits | Source subregister | Destination subregister |
---|---|---|---|
% 2 | 1 bit | dil (bit 0) | al (bit 0) |
% 256 | 8 bits | dil | al |
% 65536 | 16 bits | si | bx |
% 2³² | 32 bits | esi | ebx |
Summary
- Use
div
/idiv
for general modulo. - Use low sub-registers (
al
,ax
,eax
) for powers of two—just mask off the higher bits by moving into a smaller register and zero-extending.
Resources
Resource | Description |
---|---|
1.2 - Bit Shifts, Significant Bits, and Extracting Bytes (Intel Syntax) | Next note |