Back when I was attempting to write C programs, before I got "distracted" by asm, I didn't have much trouble with printf, but found scanf extremely unfriendly! I used to use gets (Shoot me! I didn't know any better!) followed by atoi or atof to avoid it. Learning to use it properly is probably a better solution.
I thought of using %s to discard bad (non-decimal) input, but was afraid of buffer overflow. I'm not sure where the input "goes" with your method. Man-page says "undefined", but... isn't scanf going to use whatever's on the stack as a buffer? I guess it's okay, but I'm not 100% comfortable with it. (oh, that's what that '*' does, I guess)
I'm not too happy with my latest attempt, either. I should state that I haven't got VS of any version (stubborn, I am) so I'm doing it in Linux. Mostly this involved removing underscores. Nasm will put 'em back with "--prefix _" (--postfix _" for OpenWatcom). The other issue is that bash doesn't know "pause", causing(?) a segfault at the end. Oh, wait! The segfault is from exiting with "ret 8". I was linking it without the "startup" code, exits okay with it...
Speaking of "whatever's on the stack", "tries" is used uninitialized. "inc dword [tries]" assumes zero, which may be true in Windows, but was reporting some improbable (negative) number of tries for me. Should probably explicitly initialize it, even for Windows.
I'll post what I've got so far, as is, but it isn't "right" yet!
BITS 32
[segment .text]
[global main]
; msvcrt.lib
EXTERN scanf
EXTERN printf
EXTERN rand
EXTERN srand
EXTERN time
EXTERN system
%define rnd ebp-4
%define tries ebp-8
%macro random 0
PUSH 0
CALL time
ADD esp, 4
PUSH eax
CALL srand
ADD esp, 4
CALL rand
%endmacro
main:
ENTER 8, 0
random
MOV [rnd], eax
MOV eax, [rnd]
XOR edx, edx
MOV ebx, 100
DIV ebx
ADD edx, 1
MOV [rnd], edx
; INC dword [tries]
; used uninitialized!
mov dword [tries], 1
.loop_head:
PUSH guess
CALL printf
ADD esp, 4
PUSH dword in
PUSH fmt
CALL scanf
ADD esp, 8
cmp eax, 1
jz .good
.flush_stdin:
PUSH dword in
PUSH charfmt
CALL scanf
ADD esp, 8
cmp byte [in], 10 ; LF - works for Linux!
jnz .flush_stdin
jmp .loop_head
.good:
MOV eax, dword [in]
CMP [rnd], eax
JL .less
JG .greater
JMP .loop_foot
.less:
PUSH dword [in]
PUSH less
CALL printf
ADD esp, 8
ADD dword [tries], 1
JMP .loop_head
.greater:
PUSH dword [in]
PUSH greater
CALL printf
ADD esp, 8
ADD dword [tries], 1
JMP .loop_head
.loop_foot:
PUSH dword [tries]
PUSH won
CALL printf
ADD esp, 8
PUSH pause ; Linux doesn't know "pause"!
CALL system
ADD esp, 4
LEAVE
RET 8
[segment .data]
guess: db "Guess a value between 1 and 100: ", 0
less: db "The number is lower than %d", 10, 13, 0
greater: db "The number is greater than %d", 10, 13, 0
won: db 10, 13, "You found the number in %d tries!", 10, 13, 0
fmt: db "%d", 0
charfmt db "%c", 0
pause: db "pause", 0
[segment .bss]
in: resd 1 ; user input
Best,
Frank