Since this problem involves small numbers (particularly with a small loop count of 100), it's possible to ease the modulo operation setup by simply working with 16-bit and 8-bit registers:
$$\dfrac{\text{[AX] (16-bit register)}}{\text{[other 8-bit register]}} = \text{[AH] (remainder)}$$
My main concern is with the layout. Every "basic" high-level implementation I've seen has a check and print together for each case. I've found it easier to do the same thing here, but I'm not sure if that would also be too readable in assembly.
I'm also aware that it's good to minimize register-moving. Unfortunately, I still do that with every case since I'm incrementing with one register (CX
) and using another (AX
) for the dividend. I can stick to AX
for both, but that may involve keeping a copy of the current counter value, which may just make the code a bit more complicated. I suppose it's not much of a problem here anyway.
Macros used:
nwln
- prints a newlinePutStr
- prints a defined stringPutInt
- prints a 16-bit integer value
It's not necessary to address the macros; they do work properly.
%include "macros.s"
.DATA
fizz_lbl: DB "Fizz", 0
buzz_lbl: DB "Buzz", 0
fizzbuzz_lbl: DB "FizzBuzz", 0
.CODE
.STARTUP
xor CX, CX ; counter
main_loop:
inc CX
cmp CX, 100
jg done
fizzbuzz_check:
mov AX, CX ; dividend = counter
mov BH, 15 ; divisor
div BH ; (counter / 15)
cmp AH, 0 ; counter divisible by 15?
je print_fizzbuzz ; if so, proceed with printing
jmp fizz_check ; if not, try checking for fizz
print_fizzbuzz:
PutStr fizzbuzz_lbl
nwln
jmp main_loop
fizz_check:
mov AX, CX ; dividend = counter
mov BH, 3 ; divisor
div BH ; (counter / 3)
cmp AH, 0 ; counter divisible by 3?
je print_fizz ; if so, proceed with printing
jmp buzz_check ; if not, try checking for buzz
print_fizz:
PutStr fizz_lbl
nwln
jmp main_loop
buzz_check:
mov AX, CX ; dividend = counter
mov BH, 5 ; divisor
div BH ; (counter / 5)
cmp AH, 0 ; counter divisible by 5?
je print_buzz ; if so, proceed with printing
jmp print_other ; if not, then can only display number
print_buzz:
PutStr buzz_lbl
nwln
jmp main_loop
print_other:
PutInt CX
nwln
jmp main_loop
done:
.EXIT
macros.s
? \$\endgroup\$