汇编:在Windows nasm中处理用户输入
我是asm的新手,正在尝试创建一个简单的hello世界,等待用户按下键结束.目前,hello world一切都很好,但是我从中获得的.exe控制台程序只是立即关闭,而我希望它一直显示在屏幕上,直到用户按下某个键为止. 现在我遇到的问题是,由于某种原因,该程序一直循环运行,搜索用户输入,但是当我强制关闭程序(^ C)时,我可以看到我按下的所有键都写在下一个控制台行上,例如它使用了错误的缓冲区(?)
I'm a newbie to asm and trying to make a simple hello world which awaits for the user to press a key to end. For now the hello world is all good, but the .exe console program i got from this just close instantly while i want it to stay on screen untill the user press a key. Now the problem i have is that for some reason, the program keep looping, searching for user input, but when i force close the program (^C) i can see all the keys i pressed are written on the next console line, like if it was using the wrong buffer (?)
几天来我一直在互联网上搜索修复程序,最后我寻求帮助,因为这使我发疯了^^ 我发现的所有内容主要基于int系统或linux下,而我必须处理Windows api ...
I've been searching a fix all over the internet for a few days and finally I'm asking for help cuz this is driving me crazy ^^ Everything i found is mostly based on int system or under linux, while i have to deal with the windows api...
非常感谢,欢迎您提供任何帮助或提示!
Thank you very much, any help or hint is welcome!
代码:
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 info about windows functions can be found here:
- ReadConsoleInput
- WriteConsole
push consoleInHandle
推送地址,而不是句柄.您需要push dword [consoleInHandle]
.相反,对于缓冲区,您要传递地址,因此在那里需要push buffer2
.另外,此缓冲区的大小应为INPUT_RECORD
结构的大小,我认为该大小为32个字节.
push consoleInHandle
pushes the address, not the handle. You want push dword [consoleInHandle]
. Conversely, for the buffer you want to pass the address, so you need push buffer2
there. Also, this buffer should be the size of an INPUT_RECORD
structure, which I believe is 32 bytes.
更新:正如弗兰克所说,论证顺序也是错误的.
这段代码对我有用(请注意,由于我的环境设置方式,我必须添加@xx
stdcall装饰-显然您不需要那些装饰):
Update: As Frank commented, the argument order was also wrong.
This code works for me (note I had to add the @xx
stdcall decorations due to how my environment is set up - apparently you don't need those):
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