题
我被困在这件事情,我想看看右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
的仅按位和是零。
不隶属于 StackOverflow