0

我在尝试检测 x86 汇编语言中的关键事件时遇到了麻烦。当我运行我的程序时,我得到这个一般错误:

key.exe 遇到问题,需要关闭。对此造成的不便,我们表示歉意。

我的汇编程序 fasm 生成一个 .bin 文件、一个 .exe 文件和一个 .com 文件。如果我尝试运行 .com 文件,会弹出一个消息框,提示图像文件有效,但适用于当前机器以外的机器类型。

这是我的代码:

include 'include/win32ax.inc'
section '.data' data readable writeable

inchar     DB ?
numwritten DD ?
numread    DD ?
outhandle  DD ?
inhandle   DD ?
char DB ?

     section '.text' code readable executable
     start:

    ;set up the console
invoke  AllocConsole
invoke  GetStdHandle,STD_OUTPUT_HANDLE
mov [outhandle],eax
invoke  GetStdHandle,STD_INPUT_HANDLE
mov [inhandle],eax

    ;get key press
mov ah,1h
int 21h
mov [char],AL

    ;print out the key pressed
invoke  WriteConsole,[outhandle],char,15,numwritten,0
invoke  ReadConsole,[inhandle],inchar,1,numread,0
invoke  ExitProcess,0

    .end start

我使用的是 x64 版本的 windows xp,但它与 32 位应用程序兼容。

4

1 回答 1

1

如果您正在创建 Win32 程序,则不能使用 DOS API ( int 21h ) 来获取按键。

您应该使用ReadConsoleInput函数并检查键盘事件。

这是如何做到的:

include '%fasminc%/win32ax.inc'
section '.data' data readable writeable

struc KEY_EVENT_RECORD {
  .fKeyDown       dd  ?
  .Repeat         dw  ?
  .VirtKeyCode    dw  ?
  .VirtScanCode   dw  ?
  .res            dw  ?
  .char           dd  ?
  .ctrl           dd  ?
}

struc INPUT_RECORD {
  .type  dw ?
  .event KEY_EVENT_RECORD
}

KEY_EVENT = 1

inchar     DB ?
numwritten DD ?
numread    DD ?
outhandle  DD ?
inhandle   DD ?

input      INPUT_RECORD
count      dd ?


section '.text' code readable executable

start:

        ;set up the console
        invoke  AllocConsole
        invoke  GetStdHandle,STD_OUTPUT_HANDLE
        mov [outhandle],eax
        invoke  GetStdHandle,STD_INPUT_HANDLE
        mov [inhandle],eax


.loop:
        invoke  ReadConsoleInput, [inhandle], input, 1, count
        cmp     [count], 1
        jne     .loop
        cmp     [input.type], KEY_EVENT
        jne     .loop

            ;print out the key pressed
        invoke  WriteConsole,[outhandle],input.event.char,1,numwritten,0
        invoke  ReadConsole,[inhandle],inchar,1,numread,0
        invoke  ExitProcess,0

.end start
于 2013-07-15T06:23:51.947 回答