我被困在这件事情,我想看看右shift键被按下,所以我有这样的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.I'm在86 arhitecture运行Windows 7,和我与TASM工作

有帮助吗?

解决方案

你怎么测试呢?

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

当在纯DOS(在VMWare)运行时,它可以正确显示的所有组合(0至3)。

所以,这似乎是NTVDM(DOS的Windows仿真)的神器,虽然我没有任何来源举。

我的代码:

.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

其他提示

您应该能够做清理你的检查:

test al,1
jnz rshift

我无法解释为什么你的代码不能正常工作,但你可以替换

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设置ZF如果和al AND C的仅按位和是零。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top