Why does reading input sometimes skips newline character when trying to clear input buffer?

75 Views Asked by At

When I input an odd number of characters it works as expected, but when an even number of characters is entered it waits for user input inside of the .clearBuffer procedure. I am using NASM on Windows.

global _start

extern _GetStdHandle@4
extern _WriteConsoleA@20
extern _ExitProcess@4
extern _ReadConsoleA@20

%define STDIN dword -10
%define STDOUT dword -11

section .data
    menuText: db '---menu---', 0Dh, 0Ah, 0,\
    '1. Start', 0Dh, 0Ah, 0,\
    '2. Generate field', 0Dh, 0Ah, 0,\
    '3. Settings', 0Dh, 0Ah, 0,\
    '4. Quit', 0Dh, 0Ah, 0
    inputText: db 'Enter: '
    inputTextL: equ $ - inputText
    invalid: db 'Invalid input', 0Dh, 0Ah
    invalidL: equ $ - invalid

section .bss
    stdin: resd 1
    stdout: resd 1
    
    numCharsWritten: resd 1
    numCharsRead: resd 1
    input: rest 1

section .text
_start:
    push STDOUT
    call _GetStdHandle@4
    mov [stdout], eax
    
    push STDIN
    call _GetStdHandle@4
    mov [stdin], eax
    
    call printMenu
    
    ;print "Enter: "
    mov ebx, inputTextL
    mov ecx, inputText
    call write
    
    mov ebx, 1
    mov ecx, input
    call read
    
    ;mov ebx, 1
    ;mov ecx, input
    ;call .write
    
    call clearBuffer
    
    jmp _start
    
    
printMenu:
    mov ecx, 0
    
.printMenuLoop:
    cmp ecx, 5
    jnz .printMenuText
    ret
    
.printMenuText:
    push ecx
    call .getMenuText
    
    push ecx
    mov ecx, ebx
    mov ebx, eax
    call write
    pop ecx
    add ecx, 1
    jmp near .printMenuLoop
    
;input
;index
;output
;eax - length
;ebx - str
;ecx - index
.getMenuText:
    mov eax, 0;eax - current index/length
    mov ebx, 0;ebx - offset/string
    
    cmp eax, [esp + 4]
    je .getMenuTextL2
    
.getMenuTextL1:;find string
    add ebx, 1
    cmp byte [menuText + ebx], 0
    jne .getMenuTextL1
    
    add eax, 1
    cmp eax, [esp + 4]
    jl .getMenuTextL1
    
.getMenuTextL2:
    add ebx, menuText
    pop eax
    pop ecx
    push eax
    mov eax, 0
    
.getMenuTextL3:;find length
    add eax, 1
    cmp byte [ebx + eax], 0
    jne .getMenuTextL3
    
    ret

;input
;ebx - length, ecx - string
write:
    push dword 0
    push numCharsWritten
    push ebx
    push ecx
    push dword [stdout]
    call _WriteConsoleA@20
    ret

;input
;ebx - amount, ecx - location
read:
    push dword 0
    push numCharsRead
    push ebx
    push ecx
    push dword [stdin]
    call _ReadConsoleA@20
    ret

clearBuffer:
    mov ebx, 1
    mov ecx, input
    call read
    
    ;mov ebx, 1
    ;mov ecx, input
    ;call .write
    
    cmp byte [input], 0Ah
    jne clearBuffer
    ret

;input
;eax - exit value
exit:
    push dword eax
    call _ExitProcess@4

I've tried using the _FlushConsoleInputBuffer@4 at the end of .read before the return, but that didn't do anything. I based my clear buffer code on: Clear input buffer Assembly x86 (NASM)

But as stated, it's not fully working for me.

Any help on why this is happening and how to go about fixing it would be appreciated.

0

There are 0 best solutions below