我是asm的新手,正在尝试建立一个简单的hello世界,等待用户按下键结束。目前,hello world一切都很好,但是我从中获得的.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功能的详细信息可以在这里找到:
  • ReadConsoleInput
  • WriteConsole
  • 最佳答案

    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
    

    关于windows - 组装: Dealing with user input in windows nasm,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13571791/

    10-11 22:44
    查看更多