fizzbuzz.asm en Assembly
El clásico, hablado en restos y 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
Cómo funciona
- Tres chequeos de div rutean a Fizz, Buzz o ambos.
- El camino numérico convierte hasta dos dígitos a mano.
r12guarda el contador a salvo entre syscalls.
Palabras clave y builtins usados aquí
albytedbdlglobalr12raxrcxrdirdxresbrsisection
El intento, en números
- Líneas
- 83
- Caracteres a escribir
- 1206
- Tokens
- 244
- Ritmo de tres estrellas
- 55 tpm
Al ritmo de tres estrellas de 55 tokens por minuto, este intento toma unos 266 segundos.
Paso 2 de 3 en Bis; paso 30 de 31 en Fundamentos del lenguaje.