fizzbuzz.asm in Assembly
The classic, spoken in remainders and sys_write.
; FizzBuzz 1..15: remainders decide, sys_write speaks.
global _start
section .data
fizz: db "Fizz", 10
buzz: db "Buzz", 10
both: db "FizzBuzz", 10
section .bss
numbuf: resb 4
section .text
write: ; rsi = buf, rdx = len
mov rax, 1
mov rdi, 1
syscall
ret
_start:
mov r12, 1 ; the counter, syscall-safe
.next:
; divisible by 15?
mov rax, r12
xor rdx, rdx
mov rcx, 15
div rcx
test rdx, rdx
jnz .try3
lea rsi, [both]
mov rdx, 9
call write
jmp .advance
.try3:
mov rax, r12
xor rdx, rdx
mov rcx, 3
div rcx
test rdx, rdx
jnz .try5
lea rsi, [fizz]
mov rdx, 5
call write
jmp .advance
.try5:
mov rax, r12
xor rdx, rdx
mov rcx, 5
div rcx
test rdx, rdx
jnz .number
lea rsi, [buzz]
mov rdx, 5
call write
jmp .advance
.number: ; print r12 (two digits max here)
mov rax, r12
xor rdx, rdx
mov rcx, 10
div rcx ; rax = tens, rdx = ones
mov rcx, 0 ; buffer cursor
test rax, rax
jz .ones
add al, '0'
mov [numbuf], al
inc rcx
.ones:
add dl, '0'
mov [numbuf + rcx], dl
inc rcx
mov byte [numbuf + rcx], 10
inc rcx
lea rsi, [numbuf]
mov rdx, rcx
call write
.advance:
inc r12
cmp r12, 15
jle .next
mov rax, 60
xor rdi, rdi
syscall
How it works
- Three div checks route to Fizz, Buzz, or both.
- The number path converts up to two digits by hand.
r12keeps the counter safe across syscalls.
Keywords and builtins used here
addalbytecallcmpdbdivdlglobalincjlejmpjnzjzleamovr12raxrcxrdirdxresbretrsisectionsyscalltestxor
The run, in numbers
- Lines
- 83
- Characters to type
- 1206
- Tokens
- 244
- Three-star pace
- 55 tpm
At the three-star pace of 55 tokens a minute, this run takes about 266 seconds.
Step 2 of 3 in Encore, step 30 of 31 in Language basics.