Here is my version of FizzBuss and it took me 2 1/2 hrs. I've read these little
blurbs about how this is used to test potential programmers and in fact the
overall method only took me 20 seconds to determine, but utilizing instructions
that are availiable in later CPU's took a little longer.
If there is interest in this thread I look forward to seeing others optimizations
that are tighter than mine (in ASM) and would probably work on my own version
that is better.
; Written using ML
.686P
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
Main proto
Print proto :DWORD
.data
Prompt1 db 13, 10, 13, 10, '3 & 5s Multiples', 13, 10
db '----------------', 13, 10, 0
Epilogue db 13, 10, '-- DONE --', 13, 10, 13, 10, 0
Prompt2 db 'Fiss', 0
Prompt3 db 'Buzz', 0
CRLF db 13, 10, 0
FMT db '%4d', 0
.data?
StdOut dd ?
.code
; =============================================================================
start: invoke GetStdHandle, STD_OUTPUT_HANDLE
mov StdOut, eax
invoke Print, offset Prompt1
invoke Main
invoke Print, offset Epilogue
ret
;------------------------------------------------------------------------------
Main proc
xor eax, eax ; Intiialize working registers
mov ecx, eax
xor cx, 801H
L1: inc eax ; bump counter
cmp al, 100
ja Done ; and process till 100
invoke Print, offset CRLF ; append CRLF to previous output
shl cx, 1 ; Shift mask bits for 3's & 5's
pushfd
btr ecx, 3 ; Test bit 3 and compliment if on
jnc @F ; NC if not divisible by 3
invoke Print, offset Prompt2 ; Print prompt 'Fiss'
or cl, 1 ; Reset mask
bts ecx, 31 ; and let remainder of loop know
@@: popfd ; Restore flag from previous condition
jnc @F ; and jump if bit hasn't shifted out
invoke Print, offset Prompt3
or ecx, 80000800H ; Reset orginal mask for 5's
@@: btr ecx, 31 ; Test and reset if 'Fiss' printed
jc L1 ; If bit was on skip printing number
; Print right justifed number that is not divisible by 3 or 5
push eax
push ecx
enter 20h, 0
mov edx, esp
invoke wsprintf, edx, ADDR FMT, eax
invoke Print, esp
leave
pop ecx
pop eax
jmp L1
Done: ret ; Done
Main endp
; -----------------------------------------------------------------------------
Print proc uses eax ecx lpszText:DWORD
LOCAL Written:DWORD
invoke lstrlen, lpszText
push NULL
lea ecx, Written
push ecx
push eax
push lpszText
push StdOut
call WriteFile
ret
Print endp
end start Tight_Coder_Ex
Posting Whiz in Training
215 posts since Feb 2005
Reputation Points: 47
Solved Threads: 17