2

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

我已经在互联网上搜索了几天的修复程序,最后我正在寻求帮助,因为这让我发疯了 ^^ 我发现的所有内容都主要基于 int 系统或在 linux 下,而我必须处理窗口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 信息:

4

1 回答 1

2

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

更新:正如弗兰克评论的那样,参数顺序也是错误的。这段代码对我有用(注意,由于我的环境是如何设置的,我必须添加@xxstdcall 装饰 - 显然你不需要这些):

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
于 2012-11-26T20:00:24.943 回答