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 = remainderExample
; rax = rdi % rsi
mov rax, rdi
xor rdx, rdx
div rsi
mov rax, rdx2. 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 % 65536Why This Works
-
Dividing by
2ⁿis the same as shifting rightnbits. -
The remainder is whatever’s left in the low
nbits 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/idivfor 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 |