Чтобы попрактиковаться в ассемблере в MASM, я создал небольшую программу, которая должна выполнять следующие действия:
- Вывести «Type a:» на экран
- Читать однусимвол из входного буфера, который затем сбрасывается
- Если символ «а», то оторвитесь от цикла и завершите программу, в противном случае повторите с первого шага
Мой код выглядит следующим образом:
.386
.model flat,stdcall
include \masm32\include\kernel32.inc ; Defines Symbols To Be Used for the kernel32 library
includelib \masm32\lib\kernel32.lib
STD_OUTPUT_HANDLE equ -11
STD_INPUT_HANDLE equ -10
.code
entryPt proc
local inHandle:DWORD
local outHandle:DWORD
local noOfCharsWritten:DWORD
; Get Standard Output Handle
push STD_OUTPUT_HANDLE
call GetStdHandle
mov outHandle,eax
; Get Standard Input Handle
push STD_INPUT_HANDLE
call GetStdHandle
mov inHandle,eax
.while (eax == eax) ; while (true)
; Print "Type a: "
push 0
lea eax,noOfCharsWritten
push eax
push sizeof txt
push offset txt
push outHandle
call WriteConsoleA
; Poll for a byte
call getChar
.if (al == "a") ; if the byte was "a"...
.break ; ...then end the loop
.endif
.endw
; Leave with exit code 0
push 0
call ExitProcess
entryPt endp
getChar proc
local inHandle:DWORD
local noOfCharsRead:DWORD
local resBt:BYTE
; Get the Standard Input Handle
push STD_INPUT_HANDLE
call GetStdHandle
mov inHandle,eax
; Read one char from the console, put the result in resBt and the number of chars read in noOfCharsRead
push 0
lea eax,noOfCharsRead
push eax
push 1
lea eax,resBt
push eax
push inHandle
call ReadConsoleA
; Flush Console Input Buffer
push inHandle
call FlushConsoleInputBuffer
; Return the result in the accumulator
movzx eax,resBt
ret
getChar endp
.data
txt db "Type a: "
end entryPt
Когда вы наберете «а», программа закроется, как и должно быть.Однако, если я наберу что-нибудь, что не является «a» (например, «s»), вместо того, чтобы снова запрашивать «Type a:», только один раз, вместо этого будет написано «Type a: Type a: Type a:» beforeзапрашивая еще один байт.Запись более одного не-символа приведет к еще большему количеству «Type a:».
Я подозреваю, что это потому, что ReadConsole
читает старый ввод и поэтому рано завершает функцию, но не долженFlushConsoleInputBuffer
очистили старый ввод?