Assembly 在MASM 8086组件的屏幕上显示计时器

Assembly 在MASM 8086组件的屏幕上显示计时器,assembly,timer,masm,x86-16,Assembly,Timer,Masm,X86 16,我必须在屏幕上显示时间的流逝,我一直在网上寻找,发现如何设置时间延迟,但我不知道如何在屏幕上显示它 这是我现在得到的(我甚至不知道这是不是一种方法) 为此,可以使用几种方法: 使用DOS int 21h显示文本(可能是功能9?) 使用BIOS int 10h显示字符 或者最终在B800:0000处直接写入屏幕 就我个人而言,我会使用BIOS方法。时间是一个数字,您需要将其转换为字符串才能显示它。有很多程序可以做到这一点,接下来我发布一个(程序“美元”是次要的,但是必要的): 在前面的过程中,

我必须在屏幕上显示时间的流逝,我一直在网上寻找,发现如何设置时间延迟,但我不知道如何在屏幕上显示它 这是我现在得到的(我甚至不知道这是不是一种方法)


为此,可以使用几种方法:

  • 使用DOS int 21h显示文本(可能是功能9?)

  • 使用BIOS int 10h显示字符

  • 或者最终在B800:0000处直接写入屏幕


就我个人而言,我会使用BIOS方法。

时间是一个数字,您需要将其转换为字符串才能显示它。有很多程序可以做到这一点,接下来我发布一个(程序“美元”是次要的,但是必要的):

在前面的过程中,您可以显示时间,下一个示例显示如何使用时间,它也只显示秒(我相信您可以自己显示分钟和小时),请注意,您必须在数据段中创建两个重要变量:

seconds db ?         ;◄■■ IMPORTANT VARIABLES IN DATA SEGMENT.
buf     db 6 dup (?)


display_time:          
;▼ GET SYSTEM TIME.
  mov  ah, 2ch
  int  21h       ;◄■■ SECONDS RETURN IN DH. 
;▼ TIMER (1 SECOND).  
  cmp  dh, seconds
  je   display_time  ;◄■■ REPEAT UNTIL 1 SECOND PASSED.
  mov  seconds, dh
;▼ CONVERT SECONDS TO STRING.  
  xor  ax, ax  ;◄■■ NUMBER TO CONVERT TO STRING.
  mov  al, dh  ;◄■■ SECONDS IN AX.
  lea  si, buf  ;◄■■ VARIABLE WHERE STRING WILL BE STORED.
  call number2string  ;◄■■ CALL PROCEDURE THAT CONVERTS NUMBER TO STRING.
;▼ MOVE CURSOR TO 0,0.
  mov  dl, 0  ;◄■■ X.
  mov  dh, 0  ;◄■■ Y.
  mov  ah, 2
  mov  bh, 0
  int  10h  
;▼ DISPLAY STRING.
  mov  ah, 9
  lea  dx, buf
  int  21h
  jmp  display_time

这不是一个完美的延迟过程,它在一定程度上会起作用,但偶尔会等待错误的时间。问题不清楚,您想显示什么,除了
int 1Ah
之外,还有其他服务可以获取当前设置的DOS日期/时间,但如果您想创建类似秒表的东西,则可以,它将允许您以约54毫秒的精度进行测量(即十分之一秒,而不是百分之一秒)。但是您必须创建一个更复杂的逻辑来处理所有可能的返回状态。如果有任何答案有用,您可以单击它的复选标记✔ 接受它。
;------------------------------------------
;CONVERT A NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (STR).
;PARAMETERS : AX = NUMBER TO CONVERT.
;             SI = POINTING WHERE TO STORE STRING.

proc number2string  
;FILL BUF WITH DOLLARS.
  push si
  call dollars
  pop  si

  mov  bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:       
  mov  dx, 0 ;NECESSARY TO DIVIDE BY BX.
  div  bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
  push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
  inc  cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
  cmp  ax, 0  ;IF NUMBER IS
  jne  cycle1 ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS.
cycle2:  
  pop  dx        
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
  loop cycle2  

  ret
endp

;------------------------------------------
;FILLS VARIABLE WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
;PARAMETER : SI = POINTING TO STRING TO FILL.

proc dollars                 
  mov  cx, 6
six_dollars:      
  mov  bl, '$'
  mov  [ si ], bl
  inc  si
  loop six_dollars

  ret
endp  
seconds db ?         ;◄■■ IMPORTANT VARIABLES IN DATA SEGMENT.
buf     db 6 dup (?)


display_time:          
;▼ GET SYSTEM TIME.
  mov  ah, 2ch
  int  21h       ;◄■■ SECONDS RETURN IN DH. 
;▼ TIMER (1 SECOND).  
  cmp  dh, seconds
  je   display_time  ;◄■■ REPEAT UNTIL 1 SECOND PASSED.
  mov  seconds, dh
;▼ CONVERT SECONDS TO STRING.  
  xor  ax, ax  ;◄■■ NUMBER TO CONVERT TO STRING.
  mov  al, dh  ;◄■■ SECONDS IN AX.
  lea  si, buf  ;◄■■ VARIABLE WHERE STRING WILL BE STORED.
  call number2string  ;◄■■ CALL PROCEDURE THAT CONVERTS NUMBER TO STRING.
;▼ MOVE CURSOR TO 0,0.
  mov  dl, 0  ;◄■■ X.
  mov  dh, 0  ;◄■■ Y.
  mov  ah, 2
  mov  bh, 0
  int  10h  
;▼ DISPLAY STRING.
  mov  ah, 9
  lea  dx, buf
  int  21h
  jmp  display_time