汇编:处理windows nasm中的用户输入

时间:2012-11-26 19:33:26

标签: windows assembly io nasm

我是asm的新手,并试图打造一个简单的hello世界,等待用户按键结束。现在问候世界一切都很好,但是我得到的.exe控制台程序只是立即关闭,而我希望它保持在屏幕上,直到用户按下一个键。 现在我的问题是,由于某种原因,程序保持循环,搜索用户输入,但当我强制关闭程序(^ C),我可以看到我按下的所有键都写在下一个控制台行,如果它使用了错误的缓冲区(?)

我已经在互联网上搜索了几天,最后我要求帮助因为这让我发疯了^^ 我发现的一切主要是基于int系统或linux下,而我必须处理windows api ...

非常感谢,欢迎任何帮助或提示!

代码:

STD_OUTPUT_HANDLE   equ -11
STD_INPUT_HANDLE    equ -10 
NULL                equ 0

global start
extern ExitProcess, GetStdHandle, WriteConsoleA, ReadConsoleInputA

section .data
msg                 db "Hello World!", 13, 10, 0
msg.len             equ $ - msg
consoleInHandle     dd 1

section .bss
buffer              resd 2
buffer2             resd 2

section .text
    start:

        push    STD_OUTPUT_HANDLE
        call    GetStdHandle

        push    NULL
        push    buffer
        push    msg.len
        push    msg
        push    eax
        call    WriteConsoleA 

    read:

        push STD_INPUT_HANDLE
        call GetStdHandle
        mov [consoleInHandle],eax
        push consoleInHandle
        push dword[buffer2]
        push 1
        push NULL
        call ReadConsoleInputA

        cmp eax,1
        jge exit
        jmp read

    exit:

        push    NULL
        call    ExitProcess

有关Windows功能的Moar信息可以在这里找到:

1 个答案:

答案 0 :(得分:1)

push consoleInHandle推送地址,而不是句柄。你想要push dword [consoleInHandle]。相反,对于要传递地址的缓冲区,所以需要push buffer2。此外,此缓冲区应该是INPUT_RECORD结构的大小,我相信它是32个字节。

更新:正如Frank评论的那样,参数顺序也是错误的。 这段代码适合我(注意我必须添加@xx stdcall装饰,因为我的环境设置方式 - 显然你不需要那些):

STD_OUTPUT_HANDLE   equ -11
STD_INPUT_HANDLE    equ -10
NULL                equ 0

global start
extern ExitProcess@4, GetStdHandle@4, WriteConsoleA@20, ReadConsoleInputA@16

section .data
msg                 db "Hello World!", 13, 10, 0
msg.len             equ $ - msg
consoleInHandle     dd 1

section .bss
buffer              resd 2
buffer2             resb 32

section .text
    start:

        push    STD_OUTPUT_HANDLE
        call    GetStdHandle@4

        push    NULL
        push    buffer
        push    msg.len
        push    msg
        push    eax
        call    WriteConsoleA@20

    read:

        push STD_INPUT_HANDLE
        call GetStdHandle@4
        mov [consoleInHandle],eax
        push NULL
        push 1
        push buffer2
        push dword [consoleInHandle]
        call ReadConsoleInputA@16

    exit:

        push    NULL
        call    ExitProcess@4