Skip to content

Instructions

x86-64

Shift 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

MnemonicOperationFlag notes
SHL / SALLeft shift (fill with zeros)CF = last bit shifted out; OF set for count=1
SHRLogical right shift (fill with zeros)CF = last bit shifted out
SARArithmetic right shift (sign-extend fill)CF = last bit shifted out; preserves sign
ROLRotate left (wrap MSB → LSB)CF = last bit rotated out
RORRotate right (wrap LSB → MSB)CF = last bit rotated out

Examples

asm
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:

c
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:

asm
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 4

Reverse-engineering notes

  • A chain of ror/rol/xor/add instructions is the signature of many hash functions (FNV, xxHash, SipHash) and block cipher rounds (ChaCha20, SHA-2).
  • shr rax, 3 on a pointer is often index arithmetic into an 8-byte-element array (pointer → element index).
  • sar vs shr indicates 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.