I am trying to write FizzBuzz in Assembly and I am seeing segmentation fault all the time. So far I have determined that it is not my printing routines (because I have removed their contents and the problem persists) and the error hides somewhere in the main function.
I was getting this output when I run the program:
fizzSegmentation fault
Leading me to believe that it's not the problem with using division and looking up the remainders. But I could be wrong, I haven't done Assembly in two years...
SECTION .data
global _start
fizz: db "fizz", 4
buzz: db "buzz", 4
SECTION .bss
counter: resb 1
SECTION .text
_start:
mov ax,0
mov [counter],ax
main_loop:
cmp ax,100 ;from 0 to 100
je exit ;
mov bl,3 ;divisor
mov ah,0 ;here will be a remainder
div bl ;divide
cmp ah,0 ;compare the remainder with 0
je print_fizz ;print fizz if they equal
mov bl,5 ;new divisor
mov ah,0 ;do I have to do it every time?
div bl ;divide
cmp ah,0 ;compare the remainder with 0
je print_buzz ;print buzz if they equal
jmp print_ax ;print contents of ax if not
inc ax ;increment ax
jmp main_loop ;jump to label
print_ax:
ret
print_fizz:
ret
print_buzz:
ret
exit:
mov rax,1
mov rbx,0
int 80h
ret
I am compiling using:
yasm -f elf64 -o fizzbuzz.o fizzbuzz.asm
ld -d -o fizzbuzz fizzbuzz.o
This is causing the segmentation fault:
...
je print_fizz ;print fizz if they equal
...
je print_buzz ;print buzz if they equal
jmp print_ax ;print contents of ax if not
...
print_ax:
ret
print_fizz:
ret
print_buzz:
ret
...
Since you jump to the functions, the ret
gets no return address and will return anywhere. Change it to a call/ret
-pair:
...
; je print_fizz ;print fizz if they equal
jne .1 ;skip if not equal
call print_fizz
.1:
...
; je print_buzz ;print buzz if they equal
jne .2 ;skip if not equal
call print_buzz
.2:
; jmp print_ax ;print contents of ax if not
call print_ax
...
This will cause an infinite loop:
mov ax,0
mov [counter],ax
main_loop:
cmp ax,100 ;from 0 to 100
je exit
...
mov ah,0 ;here will be a remainder
div bl ;divide
...
mov ah,0 ;do I have to do it every time?
div bl ;divide
...
inc ax ;increment ax
jmp main_loop ;jump to label
AX
changes its values and is unfit to hold the loop-counter. I suggest:
...
main_loop:
; cmp ax,100 ;from 0 to 100
cmp byte [counter], 100
...
; inc ax ;increment ax
inc byte [counter]
jmp main_loop ;jump to label
...