Saturday, April 16, 2016

Solving the fizzbuzz problem in Assembly code

Hello ladies and gentlemen, also the loyal readers of my blog. In this post, we will not be working with optimization techniques. Instead, I will share a small challenge that I worked on. Working on a small challenge can be a good way of relieving stress at the end of the day.

For those who don't know, the problem is about replacing a number that is multiple of 3 or 5 by Fizz or Buzz,respectively. Numbers that are multiple of both 3 and 5 should be replaced by "FizzBuzz".

More information about the problem can be found  here.

This problem can be easily solved using a high-level programming language, but if you use Assembly language instead, it's harder.

That's basically what I am going to share with you. I solved fizzbuzz using x86-64 Assembly with Intel syntax.

Let's take a look at the code:

;; Author: CoolerVoid
;;
;; https://en.wikipedia.org/wiki/Fizz_buzz
;; for multiples of three print "Fizz" instead of the number, and for the multiples of five print "Buzz".
;; For numbers which are multiples of both three and five print "FizzBuzz".
;;
;; $ nasm -g -f elf64 fizz_buzz_game.asm -o buzz.o
;; $ ld -m elf_x86_64 buzz.o -o gamebuzz; ./gamebuzz
section .data
 tick db 'tick'
 fizz db 'fizz'
 buzz db 'buzz'
 newline db 0xA
section .bss
 three resb 1      
 five resb 1      
 zero resb 1      

section .text
global _start

_start:
 xor si, si
 mov si,      0xFF
 mov [three], byte 0x3
 mov [five],  byte 0x5

Loop:
 push si   
 mov [zero], byte 1
 sub [three], byte 1
 mov bl, [three]
 cmp [three], byte 0
 jne Zero_Fizz
 mov [three], byte 3
Zero_Fizz: 
 xor rax, rax   
 cmp bl, 0x0
 jnz Not_Fizz
 mov [zero], byte 0
 mov rax, 4              ; syscall write()
 mov rbx, 1
 mov rcx, fizz
 mov rdx, 4
 int 0x80
Not_Fizz:
 sub [five], byte 1
 mov bl, [five]

 cmp [five], byte 0
 jne Zero_Buzz
 mov [five], byte 5
Zero_Buzz: 
 xor rax, rax  
 cmp bl, 0x0
 jnz Not_Buzz
 mov [zero], byte 0
 mov rax, 4           ; syscall write()
 mov rbx, 1
 mov rcx, buzz
 mov rdx, 4
 int 0x80
Not_Buzz:
 xor rax, rax
 mov al, [zero]
 cmp al, 0x0
 jz Not_Tick
 mov rax, 4         ; syscall write()
 mov rbx, 1
 mov rcx, tick
 mov rdx, 4
 int 0x80
Not_Tick:
 push 0x0
 xor rax, rax
 mov rax, 4         ; syscall write()
 mov rbx, 1
 mov rcx, newline
 mov rdx, 1
 int 0x80
 pop rax
    
 pop si
 dec si
 jnz Loop
    
 mov rax, 1        ; syscall exit()
 mov rbx, 0
 int 0x80


If you have familiarity with Assembly, you will notice that the solution is simple. For those unfamiliar, Assembly is not hard, but it does require that the programmer pays attention to slight details.

If you have doubt you can decrease value 0xFF at line 24, and try run again...its all right in do this...

My fifty cents ! CHEERS !



No comments:

Post a Comment