Winapi 处理ReadConsoleEA的用户输入溢出。是否清除以前的输入?

Winapi 处理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

我想使用/masm32/lib/kernel32.lib中的ReadConsoleA原型从控制台获取用户输入

如果用户输入的字符数小于最大字符数,则程序运行正常,但如果用户输入的字符数过多,则程序会将多余的字符用于下一次输入

语言:MASM x86
计算机: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