如果没有按键被按下,检查按键而不阻塞
Check for keypress without blocking if no key was pressed
我正在创建一个应用程序来查看当前时间,并且我创建了一个循环来每秒更新时间。循环看起来像这样
UPDATE:
;The code to be re-executed
JMP UPDATE
但我无法结束它。当我使用
MOV AH, 00H
INT 21H
为了捕获任何按下的键,应用程序停止并等待按键。我不希望发生这种情况;当用户点击 escape
时,应用程序应该正常运行并结束循环
最好的方法是什么?
每当您在 DOS 编程期间需要某些服务时,请查看 Ralf Brown's interrupt list。
特别是,键盘相关服务属于 int 16h
类别。
Int 16/AH=01h
是 CHECK FOR KEYSTROKE 这正是您所需要的:在 returns 之后,ZF
1 是 set2 如果没有击键可用; AL
和 AH
也包含所按下键的 ASCII 码和扫描码。
单独使用它是不够的,因为它不会从缓冲区中删除击键,所以如果用户按下 AB ESC,单独使用 CHECK FOR KEYSTROKE 总是 return A 可用。
您可以使用 Int 16/AH=00h
、GET KEYSTROKE 从缓冲区中读取和删除击键而不回显它。
您也可以使用 Int 21/AH=01h
to read a character and echo it3, note that despite what is stated in your question, Int 21/AH=00h
与此任务完全无关,因为它是 TERMINATE PROGRAM.
最后 ESC 的 ASCII 码是 27 或 1bh。
这是一个示例 COM 程序,循环直到按下 ESC。
BITS 16
ORG 100h
_loop:
;
; L O O P S T U F F
;
;Show a greeting message
mov ah, 09h
mov dx, strGreetings
int 21h
;
; K E Y S C H E C K
;
;Check for a keystroke
mov ah, 01h
int 16h
jz _loop ;ZF is set if no keystroke available
;A keystroke is present, remove it from the buffer
;so that we always check the last key pressed by the user
xor ah, ah
int 16h
;AL = ASCII code
;AH = Scancode
;Check the key was ESC
cmp al, ESC_ASCII_CODE
jne _loop
;
; T E R M I N A T I O N
;
mov ax, 4c00h
int 21h
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
; [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;
;D A T A
;
strGreetings db "Hello!", 13, 10, 24h
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
; [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;
;E Q U A L S
;
ESC_ASCII_CODE EQU 27
1零标志,可以根据它跳转jz/je
(设置则跳转)或jnz/jne
(设置则跳转)清晰)。
2 将此视为:设置为零是因为击键次数为零。
3 虽然我认为这并不适合不可打印的字符。
我正在创建一个应用程序来查看当前时间,并且我创建了一个循环来每秒更新时间。循环看起来像这样
UPDATE:
;The code to be re-executed
JMP UPDATE
但我无法结束它。当我使用
MOV AH, 00H
INT 21H
为了捕获任何按下的键,应用程序停止并等待按键。我不希望发生这种情况;当用户点击 escape
时,应用程序应该正常运行并结束循环最好的方法是什么?
每当您在 DOS 编程期间需要某些服务时,请查看 Ralf Brown's interrupt list。
特别是,键盘相关服务属于 int 16h
类别。
Int 16/AH=01h
是 CHECK FOR KEYSTROKE 这正是您所需要的:在 returns 之后,ZF
1 是 set2 如果没有击键可用; AL
和 AH
也包含所按下键的 ASCII 码和扫描码。
单独使用它是不够的,因为它不会从缓冲区中删除击键,所以如果用户按下 AB ESC,单独使用 CHECK FOR KEYSTROKE 总是 return A 可用。
您可以使用 Int 16/AH=00h
、GET KEYSTROKE 从缓冲区中读取和删除击键而不回显它。
您也可以使用 Int 21/AH=01h
to read a character and echo it3, note that despite what is stated in your question, Int 21/AH=00h
与此任务完全无关,因为它是 TERMINATE PROGRAM.
最后 ESC 的 ASCII 码是 27 或 1bh。
这是一个示例 COM 程序,循环直到按下 ESC。
BITS 16
ORG 100h
_loop:
;
; L O O P S T U F F
;
;Show a greeting message
mov ah, 09h
mov dx, strGreetings
int 21h
;
; K E Y S C H E C K
;
;Check for a keystroke
mov ah, 01h
int 16h
jz _loop ;ZF is set if no keystroke available
;A keystroke is present, remove it from the buffer
;so that we always check the last key pressed by the user
xor ah, ah
int 16h
;AL = ASCII code
;AH = Scancode
;Check the key was ESC
cmp al, ESC_ASCII_CODE
jne _loop
;
; T E R M I N A T I O N
;
mov ax, 4c00h
int 21h
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
; [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;
;D A T A
;
strGreetings db "Hello!", 13, 10, 24h
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
; [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;[ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ] [ o ]
;
;E Q U A L S
;
ESC_ASCII_CODE EQU 27
1零标志,可以根据它跳转jz/je
(设置则跳转)或jnz/jne
(设置则跳转)清晰)。
2 将此视为:设置为零是因为击键次数为零。
3 虽然我认为这并不适合不可打印的字符。