2009-11-10 105 views
4

我被困在這件事情,我想看看右shift鍵被按下,所以我有這樣的assambler代碼:8086彙編,INT 16,2

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運行Windows 7上的x86 arhitecture,和我與TASM工作

回答

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 
+0

這應該是怎麼工作的?在運行程序之前,我是否必須按shift鍵,我已經測試過它,並且總是顯示結果爲零。我正在運行Win 7 x86,並且我用tasm進行了測試 – 2009-11-11 15:59:47

+0

是的,您必須事先按shift鍵,因爲代碼沒有延遲(儘管不難添加延遲或將此代碼包裝到循環中)。在Windows下,你也可以這樣做:'ping -n 5 localhost && test.exe'(假設test.exe是上面的程序),並且在5秒鐘內按住(和保持)所需的鍵。 – atzz 2009-11-11 22:35:25

+0

我已經開始考慮循環了......在Windows命令行中運行以下命令,您將能夠看到「交互式」更改的結果:) 'for/L%I in(1,1,10000) (ping -n 2 localhost> nul&test.exe)' (對不起,我目前沒有Windows在我附近,所以上面的行沒有經過測試) – atzz 2009-11-11 22:47:33

0

我無法解釋爲什麼你的代碼不能正常工作,但可以更換

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

通過

test al, 1 

如果在裝配中有這樣一個成語,那麼它會做同樣的事情,並且更加地道。

編輯: 正如Michael在下面的評論中指出的,如果您使用test指令,則需要反轉條件跳轉。 test al, C設置ZF當且僅僅按位和alC爲零。

+1

由於魯本的答案在間接地暗示,你,如果你正在使用的測試指令需要JNZ而不是JE(ZF = 1,如果在掩碼匹配任何位,JE測試ZF = 0)。 – 2009-11-10 23:04:45

+0

現在你讓我感到困惑。我認爲你是對的,有必要扭轉條件跳躍,但我認爲你的評論的括號部分是全部倒退。如果沒有位匹配,ZF = 1,並且'je'測試ZF = 1,對吧? – 2009-11-10 23:25:28

+0

呃,對,當然 - 我的不好,那就是當你在漫長的一天過後熬夜時會發生什麼。 – 2009-11-10 23:33:05

1

,你應該能夠做清理你的檢查:

test al,1 
jnz rshift 
+0

我仍然轉移al? – 2009-11-10 22:56:23

+0

我明白了,如果我想檢查第二位,那麼我需要右移一位,對不對? – 2009-11-10 22:58:45

+0

@John不,在這種情況下,使用'test al,2'。 – 2009-11-10 23:00:25