- Use
SI
to reset the BX
pointer to 100H
, since DOS sets SI
initially to 100H
(ref). Use that to reset BX
instead of an imm
. (-1 byte)
- Instead of using a 3/5 counter in
DXDH
/DL
, use AAM
for modulo operations on counter. IMHO, AAM
is a really underrated2 byte instruction since it'sthat's effectively a byte-length DIV
using only 2 bytes that can accept an imm
value as the divisor and also sets ZF
if AL mod n = 0
. @Peter Cordes touches on this in his very brilliant post about FizzBuzz in assembly. (-5 bytes)
- Instead of CR/LF, use LF/CR (the order doesn't matter to DOS). This translates to an instruction that does not modify the defaultstartup value of
AX
, thus (in fact it zeroes out AL
) so we can eliminate the xor ax,ax
and save two bytes. It does come at a cost because 0A 0D
is only a two-byte instruction so the rest of the 24xx
instruction needs to be padded with one more byte. (-1 bytesbyte)
0A 0D or cl, [di] ; LF and CR bytes (newline)
24 00 and al, 0 ; DOS string delim ('$') + pad byte
B1 64 mov cl, 100 ; set loop counter set to 100
main_loop:
8B DE mov bx, si ; init bx to 100h
40 inc ax ; increment fizzfizzbuzz counter
50 push ax ; save fizzfizzbuzz counter
50 push ax ; save ax from getting clobbered by AAM
D4 05 aam 5 ; AL = AL mod 5, ZF if AL = 0
58 pop ax ; restore ax
75 0A jnz short buzz_done ; jump if not a 'Fizz'
83 EB 04 sub bx, 4 ; offset for output string
66C707 7A7A7542 mov dword ptr [bx], 'zzuB'
buzz_done:
50 push ax
D4 03 aam 3 ; AL = AL mod 3, ZF if AL = 0
58 pop ax
75 0A jnz short fizz_done ; jump if not a 'Buzz'
83 EB 04 sub bx, 4
66C707 7A7A6946 mov dword ptr [bx], 'zziF'
fizz_done:
84 FF test bh, bh ; either a Fizz or a Buzz? (BX not changed)
74 0C jz short num_done ; if so, do not display a digit
decimal_loop:
D4 0A aam; ; AL = AL mod 10
04 30 add al, '0' ; convert to ASCII
4B dec bx
88 07 mov [bx], al
C1 E8 08 shr ax, 8 ; 'mov al, ah', thatZF setsif ZFAL -= nice!0
75 F4 jnz decimal_loop
num_done:
8B D3 mov dx, bx ; set dx to output string pointer
B4 09 mov ah, 9
CD 21 int 21h
58 pop ax ; restore fizzfizzbuzz counter
E2 C3 loop main_loop
C3 ret