4

我被这个东西卡住了,我想看看是否按下了右移按钮,所以我有这个 assambler 代码:

mov ah,2
int 16h           ;calling INT 16,2 - Read Keyboard Flags interrupt      
mov ah,10000000b
shl al,7 
and al,10000000b
cmp al,ah         ;check if first bit is 1
je rshift 
jmp final


rshift:
mov ah,9
lea dx,rsh  ;rsh is a string that says that "right shift button has been pressed"
int 21h
jmp final  

final:             ; quit program
mov ax,4c00h
int 21h

为什么它不工作?,我认为问题是 int 16,2 不能正常工作,如果是这样,为什么会这样?这是 INT 16,2 应该做的:

AH = 02
on return:
AL = BIOS keyboard flags (located in BIOS Data Area 40:17)

|7|6|5|4|3|2|1|0|  AL or BIOS Data Area 40:17
| | | | | | | `---- right shift key depressed
| | | | | | `----- left shift key depressed
| | | | | `------ CTRL key depressed
| | | | `------- ALT key depressed
| | | `-------- scroll-lock is active
| | `--------- num-lock is active
| `---------- caps-lock is active
`----------- insert is active

我从来没有看到这条消息,我在调试中查看了 AL 寄存器,在我调用 INT 16,2 后它似乎没有改变。我在 x86 架构上运行 Win 7,我正在使用 tasm

4

3 回答 3

2

你如何测试这个?

出于好奇,我做了一个简单的程序(代码如下)。在 Windows 控制台下运行时,它检测到左移 ( Result: 2) 但从不检测到右移(预期Result: 1的,但只有得到Result: 0)。

在纯 DOS 下运行时(在 VMWare 中),它正确显示所有组合(0 到 3)。

所以它似乎是 NTVDM(Windows DOS 仿真)的产物,尽管我没有任何资料可以引用。

我的代码:

.model small

.code

start:
    mov ax, seg msg
    mov ds, ax

    mov ah, 2
    int 16h

    and al,3        ; get two lower bits - both SHIFTs
    add digit, al   ; convert to decimal

    lea dx, msg
    mov ah, 9
    int 21h

    mov ax, 4c00h
    int 21h

.data

msg     db  'Result: '
digit   db  '0'
        db  13,10,'$',0

.stack
        db  16384 dup(?)

end start
于 2009-11-11T12:17:37.857 回答
1

您应该可以通过以下方式清理您的支票:

test al,1
jnz rshift
于 2009-11-10T22:52:58.810 回答
0

我无法解释为什么您的代码不起作用,但您可以替换

mov ah,10000000b
shl al,7 
and al,10000000b
cmp al,ah         ;check if first bit is 1

经过

test al, 1

如果在装配中有成语这样的东西,它会做同样的事情并且更惯用。

编辑:正如迈克尔在下面的评论中指出的那样,如果您使用该test指令,则需要反转条件跳转。test al, C当且仅alAND的按位与C为零时,设置 ZF。

于 2009-11-10T22:50:54.133 回答