int 16h/ah=1 repeatedly gives the same key press e

2020-05-09 17:42发布

问题:

I am writing code of a game in assembly language where the movement of the dinosaur depends on the key pressed from user. I have implemented my code in a way that if the user presses space bar the program should terminate and the dinosaur should move in a right direction on pressing "a". But I am facing a problem that after pressing any key for the first time the program doesn't look for any other key which is pressed after that which shows it is taking the first pressed key again and again. How to fix it?

I am using the function of mov ah, 01h and int 16h which returns ascii of pressed key in al register. after this I compare this with required ascii keys but this 16h is doing well only when any key is pressed for the first time.

label2: 
        mov ah, 1h
    int 16h
    mov keyboardkey, al        ;keyboardkey is variable for storing ascii of key pressed

    .IF( keyboardkey == 32 )
        ret
    .ENDIF

    .IF( keyboardkey == 97 )
            mov bx, startingXaxis
            add bx, 10
            mov startingXaxis, bx
            call drawdinosaour
    .ENDIF

    .IF (keyboardkey == 98 )
        mov bx, startingXaxis
        sub bx, 10
        mov startingXaxis, bx
        call drawdinosaur
    .ENDIF  

        call delay              ;this function passes the program for 1/4 second
        jmp label2

I was expecting that whenever i press spacebar the program will terminate but it only picks the key pressed for the first time and after that it keeps on acting according to that first key and doesn't look for any key that is pressed afterwards

回答1:

The int 0x16, ah =0x01 doesn't remove the key from the buffer, and (if no key was pressed) doesn't wait until the user presses a key.

The int 0x16, ah =0x00 does remove the key from the buffer, and (if no key was pressed) does wait until the user presses a key.

If you want to remove the key from the buffer but don't want to wait until a key is pressed; then you have to use both functions, sort of like:

    mov ah,0x01
    int 0x16
    jz .doneKeypress
    mov ah,0x00
    int 0x16
    call handleKeypress
.doneKeypress:

For what you're doing (with a delay, where the user could press multiple keys while you're doing the delay); you probably want something more like:

mainLoop:

;Handle all keypresses

.nextKey:
    mov ah,0x01
    int 0x16
    jz .doneKeypresses
    mov ah,0x00
    int 0x16
    call handleKeypress
    jmp .nextKey
.doneKeypresses:

;Update the screen

     call updateScreen

;Do the delay

    call delay

;Keep doing the loop while the game is running (and stop when the game stops)

    cmp byte [isRunning],0
    je mainLoop
    ret