Assembly-01: Collatz Conjecture in x64
Implementing the Collatz Conjecture in x86-64 assembly featuring optimized bit manipulation, LEA arithmetic, and C runtime integration via NASM.
Another day, another low-level challenge. This time we’re implementing the Collatz Conjecture in raw x86-64 NASM optimized with bit tricks and runtime integration. If you’re into bare-metal logic and tight loops, this one’s for you.
The prompt comes from Exercism.com. It’s simple on paper but forces you to reason through real control flow and register juggling.
The Problem: Collatz in Assembly
Rules are simple:
- Start with a positive integer
n
- If it’s even →
n = n / 2
- If it’s odd →
n = 3n + 1
- Repeat until
n == 1
- Count how many steps that takes
Your job: write this in NASM.
Requirements
What we’re building:
- Input via
argv[]
- Output via
printf
- Uses
atoi
to parse string to int
Highlights & Optimizations
Register Discipline
Register | Purpose |
---|---|
edi |
argc |
rsi |
argv pointer |
eax |
return value, intermediate |
edx |
Collatz value |
ecx |
step counter |
Fast Math, No Loops Wasted
- Even check:
test dl, 1
→ avoids modulo - 3n+1:
lea edx, [edx + edx*2 + 1]
→ noimul
, noadd
- Divide by 2:
shr edx, 1
→ no division
The Code
section .data
fmt db "%d", 10, 0
usage db "Usage: ./program <number>", 10, 0
section .text
global main
extern printf
extern atoi
main:
push rbp
mov rbp, rsp
sub rsp, 16
cmp edi, 2
jne .usage_error
mov rdi, [rsi + 8]
call atoi
test eax, eax
jle .input_error
mov edx, eax
xor ecx, ecx
.collatz_loop:
cmp edx, 1
je .print_result
test dl, 1
jz .even_case
lea edx, [edx + edx*2 + 1]
jmp .increment_counter
.even_case:
shr edx, 1
.increment_counter:
inc ecx
jmp .collatz_loop
.input_error:
mov ecx, -1
jmp .print_result
.usage_error:
mov rdi, usage
xor eax, eax
call printf
mov eax, 1
jmp .cleanup
.print_result:
mov rdi, fmt
mov esi, ecx
xor eax, eax
call printf
xor eax, eax
.cleanup:
add rsp, 16
pop rbp
ret
%ifidn __OUTPUT_FORMAT__,elf64
section .note.GNU-stack noalloc noexec nowrite progbits
%endif
This is a great warmup for writing tight loops and thinking like a CPU. Props to Exercism for the inspiration.
Next up: maybe we’ll write the inverse. Or optimize it into oblivion.
Until then—keep it minimal, fast, and aligned.