当用户遇到逃脱时结束循环

时间:2016-08-03 23:58:26

标签: assembly dos x86-16

我正在创建一个应用程序来查看当前时间,我创建了一个循环来更新每秒的时间。循环看起来像这样

UPDATE:
;The code to be re-executed
JMP UPDATE

但我无法结束它。当我使用

MOV AH, 00H
INT 21H

捕获任何按下的键,应用程序停止并等待按键。我不希望这种情况发生;应用程序应该正常运行并在用户遇到转义时结束循环

这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:3)

每当在DOS编程期间寻找某些服务时,请查看Ralf Brown's interrupt list

特别是,键盘相关服务属于int 16h类别 Int 16/AH=01h 检查KEYSTROKE 这正是您所需要的:在它返回后,ZF 1 set 2 如果没有按键可用; ALAH也包含按下的键的ASCII和扫描码。

但是它还不够,因为它没有从缓冲区中删除键击,所以如果用户按 A B ESC ,单独使用 CHECK FOR KEYSTROKE 将始终返回 A 可用。
您可以使用Int 16/AH=00h GET KEYSTROKE 从缓冲区中读取和删除击键而不回显它。

你也可以使用Int 21/AH=01h来阅读一个字符并回复它 3 note ,尽管你的问题已经说明了Int 21/AH=00h与此任务完全无关,因为它是 TERMINATE PROGRAM

最后 ESC 的ASCII码为27或1bh。

这是一个循环直到 ESC 的COM程序示例。

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 虽然我认为这不适合不可打印的字符。