Instructions
x86-64Shift and Rotate (SHL/SHR/SAR/ROL/ROR)
Logical and arithmetic shifts move bits left or right; rotates wrap bits around — all appear heavily in crypto, hashing, and compiler optimisations.
x86-64 provides logical shifts (SHL/SHR), arithmetic shifts (SAR/SAL),
and rotates (ROL/ROR). The shift count can be the immediate 1, an 8-bit
immediate imm8, or the register CL (low 8 bits of RCX).
Instruction summary
| Mnemonic | Operation | Flag notes |
|---|---|---|
SHL / SAL | Left shift (fill with zeros) | CF = last bit shifted out; OF set for count=1 |
SHR | Logical right shift (fill with zeros) | CF = last bit shifted out |
SAR | Arithmetic right shift (sign-extend fill) | CF = last bit shifted out; preserves sign |
ROL | Rotate left (wrap MSB → LSB) | CF = last bit rotated out |
ROR | Rotate right (wrap LSB → MSB) | CF = last bit rotated out |
Examples
shl rax, 3 ; rax *= 8 (left shift by 3 = multiply by 2^3)
shr rax, 1 ; rax /= 2 (unsigned divide by 2)
sar rax, 1 ; rax /= 2 (signed divide, preserves sign)
sar rax, cl ; variable-count arithmetic shift right
rol eax, 8 ; rotate 32-bit value left by 8 (byte-swap component)
ror rax, 17 ; used in SHA-2, xxHash, etc.Compiler multiplication/division shortcuts
Compilers aggressively replace integer multiply/divide by powers of two:
x * 8 → shl rax, 3
x / 4 → sar rax, 2 (signed) or shr rax, 2 (unsigned)For signed division, the compiler may add a correction before sar to handle
rounding toward zero:
mov rax, rdi
sar rax, 63 ; fill with sign bits (-1 or 0)
and rax, 3 ; mask to divisor-1
add rdi, rax ; adjust for rounding
sar rdi, 2 ; actual divide by 4Reverse-engineering notes
- A chain of
ror/rol/xor/addinstructions is the signature of many hash functions (FNV, xxHash, SipHash) and block cipher rounds (ChaCha20, SHA-2). shr rax, 3on a pointer is often index arithmetic into an 8-byte-element array (pointer → element index).sarvsshrindicates whether the compiler treats the value as signed or unsigned — useful for recovering variable types.rcl/rcr(rotate through carry) are rare in compiled code but appear in arbitrary-precision arithmetic and legacy cryptographic code.