Winapi 处理ReadConsoleEA的用户输入溢出。是否清除以前的输入?
我想使用/masm32/lib/kernel32.lib中的ReadConsoleA原型从控制台获取用户输入 如果用户输入的字符数小于最大字符数,则程序运行正常,但如果用户输入的字符数过多,则程序会将多余的字符用于下一次输入 语言:MASM x86Winapi 处理ReadConsoleEA的用户输入溢出。是否清除以前的输入?,winapi,assembly,x86,console-application,masm,Winapi,Assembly,X86,Console Application,Masm,我想使用/masm32/lib/kernel32.lib中的ReadConsoleA原型从控制台获取用户输入 如果用户输入的字符数小于最大字符数,则程序运行正常,但如果用户输入的字符数过多,则程序会将多余的字符用于下一次输入 语言:MASM x86 计算机:Windows10x64 Driver.asm .386 .model flat, C .stack 100h INCLUDELIB /masm32/lib/kernel32.lib GetStdHandle PROTO Near32 ST
计算机:Windows10x64 Driver.asm
.386
.model flat, C
.stack 100h
INCLUDELIB /masm32/lib/kernel32.lib
GetStdHandle PROTO Near32 STDCALL, nStdHandle: DWORD
WriteConsoleA PROTO Near32 STDCALL, handle:DWORD, lpBuffer:PTR BYTE, nNumberOfBytesToWrite:DWORD, lpNumberOfBytesWritten:PTR DWORD, lpReserved:DWORD
ReadConsoleA PROTO Near32 STDCALL, handle:DWORD, lpBuffer:PTR BYTE, nNumberOfCharsToRead:DWORD, lpNumberOfCharsRead:PTR DWORD, lpVoid:DWORD
ExitProcess PROTO STDCALL, dwExitCode:DWORD
StrInput PROTO, addrStr:DWORD, dNumCharsToRead:DWORD
StrPrint PROTO, addrStr:DWORD
StrLen PROTO, addrStr:DWORD
.DATA
strPromptName db "Enter your name: ", 0
strInputName db 10 DUP(0)
strNewLine db 13, 10, 0
.CODE
Main PROC
MOV EAX, 0
; Ask for name, store it, print it, new line
INVOKE StrPrint, ADDR strPromptName
INVOKE StrInput, ADDR strInputName, LENGTHOF strInputName
INVOKE StrPrint, ADDR strInputName
INVOKE StrPrint, ADDR strNewLine
; Ask for name, store it, print it, new line
INVOKE StrPrint, ADDR strPromptName
INVOKE StrInput, ADDR strInputName, LENGTHOF strInputName
INVOKE StrPrint, ADDR strInputName
INVOKE StrPrint, ADDR strNewLine
INVOKE ExitProcess, 0
Main ENDP
StrInput PROC PUBLIC addrStr:DWORD, dNumCharsToRead:DWORD
.DATA
dNumCharsRead dd ? ; Holds the number of chars read from console
.CODE
PUSHAD ; Store all registers, don't trust others' functions
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, addrStr, dNumCharsToRead, OFFSET dNumCharsRead, 0
MOV EDI, addrStr ; Goto front of string
ADD EDI, dNumCharsRead ; Goto just after last inputted char
SUB EDI, 2 ; Go back 2, to carriage return char
MOV BYTE PTR [EDI], 0 ; Change to 0 for null termination
POPAD ; Restore all registers
RET ; No return value, return to caller
StrInput ENDP
StrPrint PROC PUBLIC addrStr:DWORD
PUSHAD ; Store all registers, don't trust others' functions
INVOKE StrLen, addrStr ; Length in ECX
DEC ECX ; Don't print null terminator
INVOKE GetStdHandle, -11 ; Standard output = -11, handle in EAX
INVOKE WriteConsoleA, EAX, addrStr, ECX, 0, 0
POPAD ; Restore all registers
RET ; No return value, return to caller
StrPrint ENDP
StrLen PROC PUBLIC uses AX EDI addrStr:DWORD
MOV EDI, addrStr ; Store address for scanning
XOR AL, AL ; Store null term for scanning
MOV ECX, -1 ; ECX = len, will decrement over string (neg len)
CLD ; Clear direction flag, search forward
REPNE SCASB ; While char not 0, continue scanning
NEG ECX ; Make length positive
DEC ECX ; Off by one
RET ; Len in ECX, return to caller
StrLen ENDP
END Main
良好的终端输出
Enter your name: abcdef << Allowed user input
abcdef
Enter your name: new << Allowed user input
new
Press any key to continue . . .
输入您的姓名:abcdef谢谢!我更改了StrInput并添加了FlushInputBuffer PROC,如下所示
任何关于更干净代码的提示或建议都将不胜感激,但我的问题已经得到了适当的回答
StrInput PROC PUBLIC addrStr:DWORD, dNumCharsToRead:DWORD
.DATA
dNumCharsRead dd ? ; Holds the number of chars read from console
.CODE
PUSHAD ; Store all registers, don't trust others' functions
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, addrStr, dNumCharsToRead, OFFSET dNumCharsRead,
MOV EDI, addrStr ; Goto front of string
ADD EDI, dNumCharsRead ; Goto last inputted char
DEC EDI ; Back one, to last inputted char
CMP BYTE PTR [EDI], 0Ah ; Check if is line feed char
JE done ; If is, done
INVOKE FlushInputBuffer ; Else, clear all input
done:
DEC EDI ; Goto 0Dh char (2nd last char)
MOV BYTE PTR [EDI], 0 ; Set to zero for null termination
POPAD ; Restore all registers
RET ; No return value, return to caller
StrInput ENDP
FlushInputBuffer PROC
.DATA
strDummy db 255 DUP (?) ; Holds input overflow, dummy variable
dNumRead dd ? ; Holds number of chars read
.CODE
PUSHAD ; Store all registers, don't trust others' functions
flush_loop:
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, ADDR strDummy, 255, ADDR dNumRead, 0
MOV EAX, dNumRead ; Store num read for comparison
CMP EAX, 255 ; If is less than 255, done reading
JE flush_loop ; Else keep reading
POPAD ; Restore all registers
RET ; Return to caller
FlushinputBuffer ENDP
谢谢,我不知道我怎么会错过这个,但它很好地回答了我的问题!
StrInput PROC PUBLIC addrStr:DWORD, dNumCharsToRead:DWORD
.DATA
dNumCharsRead dd ? ; Holds the number of chars read from console
.CODE
PUSHAD ; Store all registers, don't trust others' functions
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, addrStr, dNumCharsToRead, OFFSET dNumCharsRead,
MOV EDI, addrStr ; Goto front of string
ADD EDI, dNumCharsRead ; Goto last inputted char
DEC EDI ; Back one, to last inputted char
CMP BYTE PTR [EDI], 0Ah ; Check if is line feed char
JE done ; If is, done
INVOKE FlushInputBuffer ; Else, clear all input
done:
DEC EDI ; Goto 0Dh char (2nd last char)
MOV BYTE PTR [EDI], 0 ; Set to zero for null termination
POPAD ; Restore all registers
RET ; No return value, return to caller
StrInput ENDP
FlushInputBuffer PROC
.DATA
strDummy db 255 DUP (?) ; Holds input overflow, dummy variable
dNumRead dd ? ; Holds number of chars read
.CODE
PUSHAD ; Store all registers, don't trust others' functions
flush_loop:
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, ADDR strDummy, 255, ADDR dNumRead, 0
MOV EAX, dNumRead ; Store num read for comparison
CMP EAX, 255 ; If is less than 255, done reading
JE flush_loop ; Else keep reading
POPAD ; Restore all registers
RET ; Return to caller
FlushinputBuffer ENDP