2009-11-10 3 views
4

Je suis coincé à cette chose, je veux voir si le bouton de déplacement vers la droite a été pressé, j'ai donc ce code assambler:8086 assembleur, 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 

pourquoi est-il ne fonctionne pas, Je pense que le problème est que int 16,2 ne fonctionne pas correctement, si oui, pourquoi est-ce? ici est ce que INT est censé 16,2 faire:

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 

Je ne vois jamais le message, je l'ai regardé le registre AL dans le débogage et il ne semble pas changer après que j'appelle INT 16, 2.I'm en cours d'exécution Win 7 sur un x86 arhitecture, et je travaille avec tasm

Répondre

2

Comment allez-vous tester cela? Par curiosité, j'ai fait un programme simple (code ci-dessous). Lorsqu'il est exécuté sous console Windows, il détecte le décalage vers la gauche (Result: 2) mais ne détecte jamais le décalage droit (Result: 1 attendu, mais seulement Result: 0). Lorsqu'il est exécuté sous DOS pur (dans VMWare), il affiche correctement toutes les combinaisons (0 à 3). Il semble donc être un artefact de NTVDM (Windows DOS émulation), mais je n'ai aucune source à citer.

Mon code:

.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

Comment est-ce censé fonctionner? Dois-je appuyer sur Maj avant d'exécuter le programme, je l'ai testé et affiche toujours le résultat zéro.Je cours Win 7 x86, et je l'ai testé avec tasm –

+0

Oui, vous devez appuyer sur shift (s) à l'avance car il n'y a pas de retard dans le code (bien qu'il ne soit pas difficile d'ajouter un délai, ou d'envelopper ce code dans une boucle). Sous Windows, vous pouvez également faire ceci: 'ping -n 5 localhost && test.exe' (en supposant que test.exe est le programme ci-dessus), et disposez de 5 secondes pour appuyer (et maintenir) les touches désirées. – atzz

+0

J'ai commencé à penser à des boucles ... Exécutez ce qui suit dans la ligne de commande de Windows, et vous serez en mesure de voir le résultat changer "interactivement" :) 'pour/L% I in (1,1,10000) fais (ping -n 2 localhost> nul & test.exe) ' (désolé, je n'ai pas Windows près de moi pour le moment, donc la ligne ci-dessus n'est pas testée) – atzz

0

Je ne peux pas expliquer pourquoi votre code ne fonctionne pas, mais vous pouvez remplacer

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

par

test al, 1 

qui fait la même chose et est plus idiomatique, s'il y a une chose comme un idiome dans l'assemblage. Comme Michael l'indique dans le commentaire ci-dessous, vous devez inverser le saut conditionnel si vous utilisez l'instruction test. test al, C définit ZF si et seulement le bitwise et de al ET C est zéro.

+1

Comme la réponse de Ruben laisse deviner indirectement, vous avez besoin d'un jnz au lieu d'un je si vous utilisez l'instruction de test (ZF = 1 si les bits dans les matchs de masque, et je tests pour ZF = 0). –

+0

Maintenant vous m'avez confus. Je pense que vous avez raison de dire qu'il est nécessaire d'inverser le saut conditionnel, mais je pense que la parenthèse de votre commentaire est tout en arrière. ZF = 1 si aucun des bits ne correspond, et 'je' teste ZF = 1, non? –

+0

Euh, bien sûr, ma mauvaise, c'est ce qui se passe quand vous restez trop tard après une longue journée. –

1

vous devriez être en mesure de nettoyer votre chèque en faisant:

test al,1 
jnz rshift 
+0

dois-je encore déplacer les bits dans al? –

+0

Je l'ai eu, que diriez-vous si je veux vérifier le deuxième bit, alors j'ai besoin de passer juste d'un bit, ai-je raison? –

+0

@John Non, utilisez 'test al, 2' dans ce cas. –