Assistant 8086, INT 16.2

I'm stuck with this, I want to see if the right toggle button is pressed, so I have the code for this assembler:

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 

Why doesn't it work? I think the problem is that int 16.2 is not working correctly, if so, why? this is what INT 16.2 should do:

 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 

I never see the message, I looked at the AL register in the debug file and did not seem to change after calling INT 16.2. I am running Win 7 in x86 architecture and I am working with tasm

+4
source share
3 answers

How do you test this?

Out of curiosity, I made a simple program (code below). When launched under the Windows console, it detects a shift to the left ( Result: 2 ), but never detects a shift to the right (expected Result: 1 , but only received Result: 0 ).

When launched under a clean DOS (in VMWare), it correctly displays all combinations (from 0 to 3).

Thus, it looks like an artifact of NTVDM (Windows DOS emulation), although I have no sources to quote from.

My code is:

 .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 
+2
source

you can clear the check by doing:

 test al,1 jnz rshift 
+1
source

I can’t explain why your code is not working, but you can replace

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

by

 test al, 1 

which does the same thing and is more idiomatic if there is such a thing as an idiom in the assembly.

EDIT: As Michael points out in the comment below, you need to cancel the conditional jump if you use the test statement. test al, C sets ZF if and only bitwise and al AND C is zero.

0
source

All Articles