Bit Manipulation: popcount, ctz, abs
Use BMI/ABM instructions for branchless bit operations.
Code
; popcount(x) -> number of set bits rdi=x, result in rax
global popcount
popcount:
mov eax, edi
popcnt eax, eax ; HW popcount (SSE4.2)
ret
; ctz(x) -> count of trailing zeros (BSF)
global ctz
ctz:
bsf eax, edi ; bit scan forward -> index of lowest set bit
ret
; clz(x) -> count of leading zeros (LZCNT / BSR)
global clz
clz:
lzcnt eax, edi
ret
; abs(x) branchless: mask = x >> 31; result = (x ^ mask) - mask
global abs_int
abs_int:
mov eax, edi
cdq ; edx = sign extension of eax (all 1s if neg)
xor eax, edx ; flip bits if negative
sub eax, edx ; add 1 if negative -> |x|
ret
; Bit reversal (BSWAP for byte order)
global bswap_demo
bswap_demo:
mov eax, 0x11223344
bswap eax ; eax = 0x44332211
retExplanation
Modern x86 has hardware instructions for common bit operations: popcnt (population count), bsf/bsr (bit scan forward/reverse), lzcnt/tzcnt (leading/trailing zero count), and bswap (byte-swap for endianness). The branchless abs uses the sign-extension trick: cdq fills edx with the sign bit, XOR flips the bits if negative, and SUB adds 1 to complete two's-complement negation — no branches, no mispredictions.
More Assembly Snippets
Hello World via Linux syscall
A freestanding x86-64 program that prints and exits using only kernel syscalls.
Function Call Convention (System V AMD64)
Pass args in registers, preserve callee-saved regs, keep rsp 16-byte aligned.
Loop Summation (1..N)
Sum integers 1..N with a counted loop using dec/jnz.
strlen — Scan Until NUL
Compute C-string length by scanning memory until a zero byte.
memcpy — Copy with rep movsb
Use the rep movsb string instruction for a tight memory copy.
Read a File via syscalls
open/read/write/close a file using only Linux syscalls.