我正在汇编8086中编码游戏。我在游戏没有打开时修复了问题,但我无法修复控件。
ESC 密钥工作。当我按下它时,它将转到 _quit 函数,但是如果在此之前按下任何其他键,则控件冻结并且不在任何键上做出反应。
我的功能有问题吗?
我试图将AL
寄存器更改为AH
,但它不起作用。
_KEYCHECK:
mov ah,01h
int 16h
cmp al,1Bh ;ESC
je _QUIT
cmp al,48h ;UP
je _PLAYER.UP
cmp al,50h ;DOWN
je _PLAYER.DOWN
cmp al,4Bh ;LEFT
je _PLAYER.LEFT
cmp al,4Dh ;RIGHT
je _PLAYER.RIGHT
ret
您的 _KeyCheck 函数正在使用bios.readkeyboard status 函数。
如果没有可用键,它将通过设置Zeroflag(ZF(来通知您键盘键的可用性,或者如果键在等待时,请清除Zeroflag。在后一种情况下,您还将收到密钥的ASCII代码和scancode。
这里重要的是,可用的可用键保留在键盘缓冲区中。您在AL
和AH
中获得的信息只是预览不是实际键(从某种意义上说(。这解释了您的观察:
...但是,如果在此之前按下任何其他键
解决方案是从键盘缓冲区中删除键。这就是Bios.ReadKeyboard 字符做的。如果键在等待,它将很快返回,而从缓冲区中删除了键。如果没有可用的键,它将等到一个可用,然后从缓冲区中删除该键。
_KEYCHECK:
mov ah, 01h ; BIOS.ReadKeyboardStatus
int 16h ; -> AX ZF
jz NoKeyAvailable
mov ah, 00h ; BIOS.ReadKeyboardCharacter
int 16h ; -> AX
cmp al, 1Bh ;ESC
je _QUIT
cmp ah, 48h ;UP
je _PLAYER.UP
cmp ah, 50h ;DOWN
je _PLAYER.DOWN
cmp ah, 4Bh ;LEFT
je _PLAYER.LEFT
cmp ah, 4Dh ;RIGHT
je _PLAYER.RIGHT
NoKeyAvailable:
ret
请注意:
- 您实际上并未检查Zeroflag以找出
AL
和AH
中的信息是否有效。 - 数字1bh(esc(是ASCII代码,必须从
AL
检查,但所有其他代码48H(up(,50h(down(,4bh(左(和4DH(右(是scancodes,因此从AH
进行检查。
您使用的是INT 16H,1。正如您在这里看到的那样,特殊键(如箭头(具有称为扫描代码的值,并且扫描代码在AH中返回。尝试
mov ah,01h
int 16h
cmp al,1Bh ;ESC
je _QUIT
cmp ah,48h ;UP
je _PLAYER.UP
cmp ah,50h ;DOWN
je _PLAYER.DOWN
cmp ah,4Bh ;LEFT
je _PLAYER.LEFT
cmp ah,4Dh ;RIGHT
je _PLAYER.RIGHT
如果那不起作用,我建议您调试并检查问题是否不在另一个地方(例如,尝试在_player.up下打印某些东西(