在汇编中,我正在尝试制作动画。在下面的代码中,move_object为对象设置动画,而move_arrow为另一个对象设置动画。然而,问题是两者都使用了相同的定时器功能(实际上我不明白它是如何工作的,我只是从源代码中复制了它。)两者在正常情况下都能很好地运行。但我想做的是,对象将从一开始就保持动画,但箭头将等待用户按下特定的键。当用户按下该键时,箭头就会启动。但每当我调用键盘按压的中断功能(MOV AH,0 INT 16H)时,程序就会在那里暂停,等待用户按键。但是我想在那个时候有以前的反对者仍然移动。但无论我如何编写代码,代码似乎都会在那一行停止,而没有其他行被执行。下面是我的代码片段。
; dont know how it works , just know that it works as a timer :D
TIMER_TICK PROC
PUSH DS ; SAVE DS
PUSH AX
MOV AX,SEG TIMER_FLAG ; GET SEGMENT OF FLAG
MOV DS,AX ; PUT IN DS
MOV TIMER_FLAG,1 ; SET FLAG
; RESTORE REGISTER
POP AX
POP DS
IRET ; IT IS DIFFERENT FROM "RET". IF WE USE "IRET" THEN
; IF WILL REMAIN 1 WHICH MEANS IT CAN BE INTERRUPT AGAIN
TIMER_TICK ENDP
;; other codes
;WAIT FOR TIMER TICK BEFORE MOVING THE OBJECT
TT:
CMP TIMER_FLAG,1 ; TIMER TICKED?
JNE TT ; NO , KEEP TESTING
MOV TIMER_FLAG,0 ; YES, CLEAR FLAG
CMP LAP,1 ; CHECKS IF ARROW HAVE FINISHED CROSSING
JE GAME
CALL MOVE_OBJECT ;animates the object to a new position
CMP KEY,0
JNE CONT
MOV AH,0
INT 16H ;**whole program gets halted here untill user presses a key**
OR AL,AL
JNE EXIT
CMP AH,3BH
JNE GAME
MOV KEY,1
CONT:
; CHECK FOR KEYBOARD
CALL MOVE_ARROW ;animates the object in a new position
; DELAY 1 TIMER CLICK
TT2:
CMP TIMER_FLAG,1 ; TIMER TICKED?
JNE TT2 ; NO , KEEP TESTING
MOV TIMER_FLAG,0 ; YES , CLEAR FLAG
JMP TT ; GO GET NEXT OBJECT POSITION
;; other codes
您正在使用的BIOS功能确实会停止,直到键盘上有一个键可用。它就是这样工作的
请考虑使用函数1。如果密钥正在等待,该密钥将立即返回并通过零标志ZF报告。所以如果ZF=1,你可能会跳回到TT.
mov ah,1
int 16h
jz TT
mov ah,0
int 16h
在int 16h中使用函数ah=1。如果在调用函数ah=1之前一直按下某个键,则ZF将被设置,AX包含将被设置的值(如果使用ah=0)。否则,如果没有按键,ZF将不会设置,AX也不会包含有用的值。注意:如果你使用函数ah=1,那么如果按下了某个键,你就必须使用函数ah=0,否则键盘缓冲区就不会改变。