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 right n 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 bitsSource subregisterDestination subregister
% 21 bitdil (bit 0)al (bit 0)
% 2568 bitsdilal
% 6553616 bitssibx
% 2³²32 bitsesiebx

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