Skip to content

Instantly share code, notes, and snippets.

@vmxdev
Last active October 14, 2020 10:24
Show Gist options
  • Save vmxdev/075d1015abc2ff05b7236c2486787d85 to your computer and use it in GitHub Desktop.
Save vmxdev/075d1015abc2ff05b7236c2486787d85 to your computer and use it in GitHub Desktop.
fizzbuzz in GNU assembly
/*
* To compile and link:
*
* $ gcc -Wall -pedantic -Wextra fizzbuzz.s -no-pie -o fizzbuzz
*/
.data
/* Strings to print */
fizz: .asciz "fizz\n"
.equ fizz_len, . - fizz - 1
buzz: .asciz "buzz\n"
.equ buzz_len, . - buzz - 1
fizzbuzz: .asciz "fizzbuzz\n"
.equ fizzbuzz_len, . - fizzbuzz - 1
/* Format string for printf(), we will print number with it */
format: .asciz "%d\n"
.align 2
/* Loop counter with initial value */
i: .word 1
/* And loop limit */
.equ limit, 100 + 1
.text
/* Helper macros */
/* Print string (using write() syscall) if (i mod DIVISOR) == 0 */
.macro PRINT_STR_OR_CONTINUE DIVISOR, MSG, LEN
mov \DIVISOR, %rcx
movl i(%eip), %eax
xor %rdx, %rdx
div %rcx
/* check modulo */
or %rdx, %rdx
/* if not zero, jump to end of macro */
jnz 1f
/* else print string */
mov $1, %rax
mov $1, %rdi
mov \MSG, %rsi
mov \LEN, %rdx
syscall
/* and jump to next loop iteration */
jmp END_DO
1:
.endm
/* Print integer number using printf(format, i); format is "%d\n" */
.macro PRINT_NUMBER X
push %rbx
lea format(%rip), %rdi
xor %eax, %eax
mov \X, %esi
call printf
pop %rbx
.endm
/* Increment I and jump to DO if (I != LIMIT) */
.macro WHILE I, LIMIT
mov \I, %eax
inc %eax
mov %eax, i(%eip)
cmp \LIMIT, %eax
jne DO
.endm
/* Exit with return code "CODE" */
.macro EXIT CODE
movq $60, %rax
movq \CODE, %rdi
syscall
.endm
.globl main
.type main, @function
main:
/* entry point */
DO:
PRINT_STR_OR_CONTINUE $(3 * 5), $fizzbuzz, $fizzbuzz_len
PRINT_STR_OR_CONTINUE $3, $fizz, $fizz_len
PRINT_STR_OR_CONTINUE $5, $buzz, $buzz_len
PRINT_NUMBER i(%eip)
END_DO:
WHILE i(%eip), $limit
EXIT $0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment