2012-11-26 37 views
2

我是一個新手,想要創建一個簡單的hello世界,等待用戶按一個鍵結束。現在,你好世界都很好,但是我從這個關閉的.exe控制檯程序即時關閉,而我希望它保持在屏幕上,直到用戶按下一個鍵。 現在我遇到的問題是,由於某種原因,程序不斷循環,搜索用戶輸入,但是當我強制關閉程序(^ C)時,我可以看到我按下的所有鍵都寫在下一個控制檯行上,就像如果它使用了錯誤的緩衝區(?)彙編:處理windows中的用戶輸入nasm

我一直在尋找一個修復整個互聯網幾天,最後我尋求幫助因爲這是讓我瘋狂^^ 我發現的一切是主要基於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

我敢肯定,你想要'推DWORD [consoleInHandle]'(或者只是'push eax') - 你正在推送變量的地址。我很肯定你想'push buffer2' - 地址,而不是'[contents]'。我懷疑你推錯他們的順序 - 處理應該是最後(不太確定這一點)... –

+0

thx @Frank,我修改了這個,但是我恐怕這並不能解決問題:/ 我仍然無法檢測到任何用戶輸入,當我強制我的程序停止時,我可以看到我在下一個命令行輸入的字符... 而且,我很確定參數的順序,當我檢查他們很多次。只是簡單地看看我在第一篇文章中給出的微軟文檔鏈接:) – dyarob

回答

1

push consoleInHandle推動地址,而不是手柄。你想要push dword [consoleInHandle]。相反,對於你想要傳遞地址的緩衝區,所以你需要在那裏有push buffer2。此外,這個緩衝區應該是一個INPUT_RECORD結構的大小,我相信它是32個字節。

更新:正如弗蘭克評論的那樣,論證順序也是錯誤的。 此代碼對我的作品(請注意,我不得不添加@xx STDCALL裝飾品,由於我的環境是如何設置的 - 顯然你並不需要這些):

STD_OUTPUT_HANDLE equ -11 
STD_INPUT_HANDLE equ -10 
NULL    equ 0 

global start 
extern [email protected], [email protected], [email protected], [email protected] 

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 [email protected] 

     push NULL 
     push buffer 
     push msg.len 
     push msg 
     push eax 
     call [email protected] 

    read: 

     push STD_INPUT_HANDLE 
     call [email protected] 
     mov [consoleInHandle],eax 
     push NULL 
     push 1 
     push buffer2 
     push dword [consoleInHandle] 
     call [email protected] 

    exit: 

     push NULL 
     call [email protected] 
+0

謝謝,現在我得到了我與[]符號混淆-_- 至於de INPUT_RECORD的事情,我必須做點什麼這樣?: http://www.asmcommunity.net/board/index.php?topic=5983.0 – dyarob

+0

NB我試圖 緩衝器2 \t \t \t RESB 32 但這並不解決問題 – dyarob

+0

更新的答案有工作代碼 – Jester