⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 type1.asm

📁 type practice 一个打字练习的汇编源程序,并且可以计时
💻 ASM
字号:
;二进制数变成十进制
;用于显示时间和错误个数
.486
B_CONVERT_D MACRO TIME,NN                 ;TIME是存放在各时间单元的数值,NN分别为100,10,1
            LOCAL LAST,NEXT
	      MOV   dl, 0
            MOV   CX,TIME
LAST:       CMP   CX,NN
            JL    NEXT                    ;(TIME)<NN转
            
            SUB   CX,NN
            INC   dl
            JMP   LAST

NEXT:       ADD   dl,30h
            MOV   ah,02h
            INT   21h                     ;用于一位一位显示时间
            ENDM
            
;-------------------------------------------------------------------------------


DATA        SEGMENT USE16

mesg        DB    '          You can start your typewriting now!!            '
            DB    0DH,0AH,'$'
CONTINUE    DB    'Press any key to continue except Esc!'        
CCOUNT      EQU   $-CONTINUE

ERROR       DB    'The number of error is :'
ESCOUNT     EQU   $-ERROR

ECOUNT      DW    0                       ;用于存放错误的个数

OLD1C       DD    ?                       ;用于保存原有的1CH型中断向量

ICOUNT      DW    0                       ;用于时间统计,当其值为18约为一秒
SEC         DW    0
MIN         DW    0
HOURS       DW    0
MSEC        DW    0

str1	      db	'abcd efgh ijkl mnop qrst uvwx yz.'
            db 0dh,0ah,'$'
str2        db 'there are some newspapers on the table.'
            db 0dh,0ah,'$'
str3        db 'there are some clouds in the sky.'
            db 0dh,0ah,'$'
str4        db 'she always eats her lunch at noon.'
            db 0dh,0ah,'$'
str5        db 'i do not like autumn and winter.'
	      db 0DH,0AH,'$'


EADDR       DW    str1,str2,str3,str4,str5;存放例句的首地址

RANDSUM     DB    ?                       ;存放一随机数,用于随机显示例句
COUNT       DW    0

DATA        ENDS




CODE        SEGMENT USE16
            ASSUME CS:CODE,DS:DATA,ES:DATA
      
BEG:        MOV   AX,DATA
            MOV   DS,AX
            MOV   ES,AX

            
            CLI
            CALL  READ1C                  ;保存系统的1CH型中断向量
            CALL  WRITE1C                 ;设置自编程序的1CH型中断向量
      
            IN    AL,21H                  ;写中断屏蔽字
            AND   AL,11111110B
            OUT   21H,AL                  ;允许日时钟中断
            STI

FIRST:      MOV   AH,0                    ;清屏
            MOV   AL,3
            INT   10H
            
            MOV   ICOUNT,0                ;初始化各时间和计数单位
            MOV   MIN,0
            MOV   SEC,0
            MOV   HOURS,0
            MOV   MSEC,0
            MOV   ECOUNT,0                ;存放错误的个数

            MOV   AH,09H                  ;显示提示信息
            MOV   DX,OFFSET mesg
            INT   21H
            

            
            CALL  DISPCRLF
            CALL  RAND                    ;产生一个在{0,2,4,6,8}中的随机数
            MOV   SI,WORD PTR RANDSUM
            MOV   AH,09H
            MOV   DX,OFFSET EADDR[SI]     ;随机显示一个例句
            INT   21H
            

            
            MOV   AH,13H                  ;在指定位置显示错误个数提示,初始值为000
            MOV   AL,1
            MOV   BH,0
            MOV   BL,0eH
            MOV   DH,10
            MOV   DL,0
            MOV   CX,ESCOUNT
            MOV   BP,OFFSET ERROR
            INT   10H
            B_CONVERT_D ECOUNT,100
            B_CONVERT_D ECOUNT,10
            B_CONVERT_D ECOUNT,1
            
            
            MOV   BX,EADDR[SI]           ;将例句的首地址给BX
 	      DEC   BX
 	      
	      MOV   DL,0
            DEC   DL
            
INPUT:      INC   DL                     ;列数增加1,用于下次的字符输入
            MOV   AH,02H                 ;指定光标为止
            MOV   BH,0
            MOV   DH,3
            INT   10H

            MOV   AH,01H                 ;输入一个字符
	      INT	21H
            STI

	      CMP	AL,0DH                 ;以回车结束,显示时间信息
	      JZ    DISPINF
	      INC	BX
	      CMP	AL, BYTE PTR [BX]      ;将输入字符与例句进行比较
            JZ	L                      ;相同,继续输入

	      INC   ECOUNT
	      PUSH  ECOUNT
  	      CALL  DISPECOUNT             ;不相同,错误个数增加1
  	      POP   ECOUNT
L:          JMP   INPUT
	

DISPINF:    CLI
	      CALL  DISPCRLF
            CALL  DISPTIME                ;显示打字多用时间
            CALL  DISPCRLF
            
	
            MOV   AH,13H
            MOV   AL,1
            MOV   BH,0
            MOV   BL,0AH
            MOV   DH,11
            MOV   DL,0
            MOV   CX,CCOUNT
            MOV   BP,OFFSET CONTINUE
            INT   10H                     ;显示是否继续的提示信息
       
            MOV   AH,08H
            INT   21H                     ;按任意键
            CMP   AL,1BH
            JZ    QUIT                    ;若为Esc键退出整个程序
            CALL  DISPCRLF
            JMP   FIRST                   ;否则进行下一例句的练习

QUIT:       CALL  RESET1C                 ;恢复1CH型中断向量
            MOV   AH,4CH
            INT   21H
            
            
      
;-------------------------------------------------------------------------------
SERVICE     PROC                          ;日时钟中断服务子程序
            PUSHA
            PUSH  DS
            MOV   AX,DATA
            MOV   DS,AX                   ;重新给DS赋值
            
            MOV   BX,OFFSET ICOUNT
            INC   WORD PTR [BX]
            CMP   WORD PTR [BX],18        ;不满18,转
            JNE   EXIT
            
            
SUM:        MOV   WORD PTR [BX], 0    
            ADD   BX,2
            INC   WORD PTR[BX]
            CMP   WORD PTR[BX],60
	      JNE   EXIT
	      JMP   SUM

ADJUST:     CMP   HOURS,12
            JLE   EXIT
            SUB   HOURS,12

EXIT:       MOV   AL,20H                  ;写中断结束命令字
            OUT   20H,AL
            
            POP   DS
            POPA
            STI
            IRET
SERVICE     ENDP


;-------------------------------------------------------------------------------
READ1C      PROC                          ;保存系统1CH型中断向量
            PUSH  ES
            PUSH  DS
            MOV   AX,CODE
            MOV   DS,AX
            
            MOV   AX,351CH
            INT   21H
            MOV   WORD PTR OLD1C,BX
            MOV   WORD PTR OLD1C+2,ES
            
            POP   DS
            POP   ES
            RET
READ1C      ENDP



;-------------------------------------------------------------------------------
WRITE1C     PROC                          ;重置新的1CH型中断向量
            PUSH  DS
            MOV   AX,CODE
            MOV   DS,AX

            MOV   DX,OFFSET SERVICE
            MOV   AX,251CH
            INT   21H

            POP   DS
            RET
WRITE1C     ENDP



;-------------------------------------------------------------------------------
RESET1C     PROC                          ;恢复原1CH型中断向量
            MOV   DX,WORD PTR OLD1C
            MOV   DS,WORD PTR OLD1C+2
            MOV   AX,251CH
            INT   21H
            RET
RESET1C     ENDP


;-------------------------------------------------------------------------------
DISPTIME    PROC                          ;用于显示打字所用时间
            B_CONVERT_D MIN,100           ;显示分钟数
            MOV   MIN,CX
            B_CONVERT_D MIN,10
            MOV   MIN,CX
            B_CONVERT_D MIN,1


            MOV   AL,':'
            MOV   AH,0EH
            INT   10H


            B_CONVERT_D SEC,100           ;显示秒数
             MOV   SEC,CX
            B_CONVERT_D SEC,10
            MOV   SEC,CX
            B_CONVERT_D SEC,1


            MOV   AL,':'
            MOV   AH,0EH
            INT   10H


            MOV   AL,55
	      MOV   BL,BYTE PTR ICOUNT
            MUL   BL
            MOV   MSEC,AX                 ;将所得毫秒数放入MESC对应的内存单元
            B_CONVERT_D MSEC,100          ;显示毫秒数
            MOV   MSEC,CX
            B_CONVERT_D MSEC,10
            MOV   MSEC,CX
            B_CONVERT_D MSEC,1

            RET
DISPTIME    ENDP

;-------------------------------------------------------------------------------
DISPCRLF    PROC                          ;显示回车换行符
            MOV   AH,0EH                  ;因较频繁地使用,故将其定义为一个子程序
            MOV   AL,0DH
            INT   10H
            MOV   AH,0EH
            MOV   AL,0AH
            INT   10H
            RET
DISPCRLF    ENDP


;-------------------------------------------------------------------------------
DISPECOUNT  PROC                           ;用于统计并显示输错个数
            PUSHA

            MOV   AH,02H
            MOV   BH,0
            MOV   DH,10
            MOV   DL,ESCOUNT
            INT   10H
            
	      B_CONVERT_D ECOUNT,100
	      MOV   ECOUNT,CX
	      B_CONVERT_D ECOUNT,10
            MOV   ECOUNT,CX
            B_CONVERT_D ECOUNT,1

            POPA
            RET
DISPECOUNT   ENDP


;-------------------------------------------------------------------------------
RAND        PROC                          ;用于产生一个随机数
            PUSHA
            PUSH  DS
            MOV   AX,DATA
            MOV   DS,AX
            
            MOV   AH,2CH
            INT   21H
            MOV   AL,DH
            MOV   AH,0
            
            MOV   BL,6
            DIV   BL                      ;ax/6->ax,产生0~4之间的随机数
            
            MOV   AL,AH
            MOV   BL,2
            MUL   BL                      ;*2
            MOV   WORD PTR RANDSUM,AX     ;产生{0,2,4,6,8}中的数字
            POP   DS
	      POPA
            RET
RAND        ENDP
            
CODE        ENDS
            END    BEG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -