📄 main.asm
字号:
LF = 0AH
CR = 0DH
;宏定义部分
PRINT MACRO P1,P2 ;输出“*”
PUSH AX
PUSH BX
PUSH CX
MOV AH, 09H
MOV AL, P1
MOV BH, 0
MOV BL, P2
MOV CX, 1
INT 10H
POP CX
POP BX
POP AX
ENDM
MOVTO MACRO P1,P2 ;移动光标到指定位置
PUSH AX
PUSH DX
MOV AH, 2
MOV DH, P1
MOV DL, P2
INT 10H
POP DX
POP AX
ENDM
OUTPUT MACRO MSG,P1,P2,P3 ;输出字符串
LOCAL DIFFER, EXITOF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV DH, P2
MOV DL, P3
MOV BH, 0
MOV BL, P1
MOV DI, 0
DIFFER:
MOV AH, 02H
INT 10H
MOV CL, MSG[DI]
CMP CL, '$'
JE EXITOF
MOV AH, 9
MOV AL, MSG[DI]
MOV CX, 1
INT 10H
INC DI
INC DL
JMP DIFFER
EXITOF:
POP DI
POP DX
POP CX
POP BX
POP AX
ENDM
XIANSHI_G MACRO ;输出箭头指示符
PUSH AX
PUSH BX
PUSH CX
MOV CX, 1
MOV AH, 9
MOV AL, 19H
MOV BL, 10001100B
INT 10H
POP CX
POP BX
POP AX
ENDM
DSEG SEGMENT 'DATA'
;显示窗口内容
MSG0 DB '******WELCOME TO USE THIS SYSTEM!******$'
MSG1 DB '********MADE BY LIUZHI(20032375) 2005,11*********$'
MSG2 DB '********PRESS "ENTER" TO START!********$'
MSG3 DB '*****PRESS "SPACE" TO PAUSE!*****$'
MSG4 DB '****PRESS "ESC" TO END!****$'
MSG5 DB '*********THE PASSED TIME:$'
MSG6 DB '*****THE RATE OF CORRECT:$'
MSG7 DB '*********DO YOU WANT TO END?***********$'
MSG8 DB '******PRESS "ENTER" TO RESTART!********$'
MSG9 DB '*********PRESS " ESC" TO OUT!**********$'
MSG10 DB '****THANK YOU FOR USING THE SYSTEM!****$'
MSG11 DB ' $'
MSG12 DB '@@ PRESS "ESC" TO END!$'
MSG13 DB '*** ^ _ ^ ^ _ ^ ***$'
MSG14 DB '***** ^ _ ^ *****$'
MSG15 DB '@@ PRESS "SPACE" TO PAUSE!$'
MSG16 DB '@@ THEN PRESS "SPACE" TO START!$'
MSG17 DB '**************************^ _ ^ INSTRUCTION ^ _ ^***************************$'
MSG18 DB '@@ PRESS "BACK SPACE" TO DELETE!$'
SECONT DB 0 ;
COUNT0 DW 0 ;为了记录正确的字符数
COUNT1 DW 0 ;字符总个数
COUNT2 DW 0 ;为了到行尾时自动翻行的控制
COUNT3 DW 0 ;秒
COUNT4 DW 0 ;分
COUNT5 DW 0 ;时
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
ASSUME CS:CSEG, SS:SSEG, DS:DSEG
;*******************************************
START PROC FAR
PUSH DS
MOV AX, 0
PUSH AX
MOV AX, DSEG
MOV DS, AX
MOV ES, AX
CALL SHUCHU_K ;输出黄色外围框架
CALL SHUCHU_TISHI ;输出提示信息
LZ:
MOV AH, 1
INT 21H
MOV BL, AL
CMP AL,CR
JE PRACTISE
CMP AL,1BH
JE TZD_1
JMP LZ
PRACTISE:
CALL SHUCHU_K
MOV DH, 1
MOV DL, 1
MOVTO DH, DL
XIANSHI_G ;显示“箭头”
MOV AH, 0
INT 1AH
MOV AL, DL ;随机生成字母
CONT_1:
CMP AL, 7EH
JA CONT
CMP AL, 21H
JB CON
JMP CONTI
CONT:
SUB AL, 7EH
JMP CONT_1
CON:
ADD AL, 20H
CONTI:
MOV CX, 78
MOV AH, 9
MOV BL, 00001111B
MOV DH, 2
MOV DL, 0
JMP SHUCHU
TZD_1: ;跳转点到“EXIT”
JMP TZD_2
SHUCHU:
INC DL
MOVTO DH, DL
INT 10H
ADD AL, DL
CMP AL, 7EH
JA CONTINUE
CMP AL, 21H
JB CONTINUE1
LOOP SHUCHU
JMP DAZIRUKOU
PRACTISE4:
JMP PRACTISE
CONTINUE:
SUB AL, 7EH
CONTINUE1:
ADD AL, 20H
LOOP SHUCHU ;到此为输出上面一行要打字练习的内容
;下面开始打字练习*******************************************
DAZIRUKOU:
MOV DH, 3
MOV DL, 1
DAZI:
;显示正确率*********************************************************
PUSH DX
MOV DH, 14
MOV DL, 2
OUTPUT MSG17, 13, DH, DL
MOV DH, 15
MOV DL, 4
OUTPUT MSG18, 10, DH, DL
MOV DH, 16
MOV DL, 4
OUTPUT MSG15, 10, DH, DL
MOV DH, 17
MOV DL, 4
OUTPUT MSG16, 10, DH, DL
MOV DH, 18
MOV DL, 4
OUTPUT MSG12, 10, DH, DL
JMP DAZI1
PRACTISE3:
JMP PRACTISE4
DAZI1:
MOV DH, 20
MOV DL, 2
OUTPUT MSG5, 9, DH, DL
MOV DH, 21
MOV DL, 2
OUTPUT MSG11, 10, DH, DL
OUTPUT MSG6, 9, DH, DL
MOV DH, 21
MOV DL, 27
MOVTO DH, DL
MOV AX, COUNT0
CALL CHANGE
MOV AH, 2
MOV DL, '/'
INT 21H
MOV AX, COUNT1
CALL CHANGE
POP DX
JMP PRESS
;*******************************************************************
PRACTISE2:
JMP PRACTISE3
PRESS:
CALL TIME ;调用时间
MOVTO DH, DL
MOV AH, 01H
INT 16H
JNE KEY
JMP PRESS
KEY:
MOV AH, 00
INT 16H
CMP AL, 20h ;如果是空格就暂停
JE PAUSE
JMP ISESC
PAUSE: ;输入是空格就结束暂停
PUSH DX
MOV AH, 06H
MOV DL, 0FFH
INT 21H
POP DX
CMP AL, 20H
JNE PAUSE
ISESC:
CMP AL, 1BH
JE TZD_2
CMP AL, 08H
JE DELETE
CMP AL, 0DH
JE TZD_DAZI2
INC COUNT2
INC COUNT1 ;是上面的字符,则COUNT1加1
JMP ISEQUAL
TZD_DAZI2:
JMP DAZI
TZD_2: ;设定跳转点到“EXIT”
JMP SKIP
DELETE:
MOV AX, COUNT1
CMP AX, 0
JNE DELETE_G
JMP TZD_DAZI2
DELETE_G:
DEC COUNT1
DEC COUNT2
SUB DH, 2
MOVTO DH, DL
PRINT ' ', 0
DEC DL
MOVTO DH, DL
XIANSHI_G
ADD DH, 2
MOVTO DH, DL
MOV AH, 08H
INT 10H
CMP AH, 10 ;8号功能时, AH=属性,AH=ASC码
JNZ DEL
DEC COUNT0
DEL:
PRINT ' ',0
TZD_DAZI1: ;跳转点,到“打字”
JMP TZD_DAZI2
ISEQUAL:
MOV BL, AL
CMP AL, 21H
JB WRONG
CMP AL, 7FH
JA WRONG
SUB DH, 2
MOVTO DH, DL
PRINT ' ',0
INC DL
MOVTO DH, DL
XIANSHI_G
INC DH
DEC DL
MOVTO DH, DL
MOV AH, 8 ;读得光标处字符送到AL中
INT 10H
CMP AL, BL
JE EQUAL
CALL SOUND ;在此处添加警报声
MOV AL, BL
MOV BL, 12
JMP UNEQUAL
WRONG:
TZD_DAZI0:
JMP TZD_DAZI1
EQUAL:
INC COUNT0
MOV AL, BL
MOV BL, 10
UNEQUAL:
INC DH
MOVTO DH, DL
MOV AH, 9
MOV CX, 1
INT 10H
INC DL
MOV AX, COUNT2
CMP AL, 78
JB TZD_DAZI0
SUB AX, 78
MOV COUNT2, AX
REFLESH: ;满一行后自动刷新(78个字符)
MOV AH, 7
INT 21H
PRACTISE1:
JMP PRACTISE2
SKIP:
CALL SHUCHU_K
MOV DH, 5
MOV DL, 18
OUTPUT MSG10, 12, DH, DL
ADD DH, 2
OUTPUT MSG7, 13, DH, DL
JMP SKIP1
PRACTISE0:
JMP PRACTISE1
SKIP1:
ADD DH, 10
OUTPUT MSG8, 10, DH, DL
ADD DH, 2
OUTPUT MSG9, 11, DH, DL
JMP RESTART
PRACTICE:
JMP PRACTISE0
RESTART:
MOV AH, 00
INT 16H
CMP AL, 0DH
MOV SECONT, 0
MOV COUNT0, 0
MOV COUNT1, 0
MOV COUNT2, 0
MOV COUNT3, 0
MOV COUNT4, 0
MOV COUNT5, 0
JE PRACTICE
CMP AL, 1BH
JE EXIT
NONE: NOP
JMP RESTART
EXIT:
MOV AH, 0
MOV AL, 3
INT 10H
MOV AH, 4CH
INT 21H
RET
START ENDP
;输出外围框架****************************************
SHUCHU_K PROC
PUSH AX
PUSH CX
PUSH DX
MOV AH, 0
MOV AL, 3
INT 10H
MOV CX, 79
MOV DH, 0
MOV DL, 0
AGAIN1:
INC DL
MOVTO DH, DL
PRINT '*',0EH
LOOP AGAIN1
MOV CX, 24
AGAIN2:
INC DH
MOVTO DH, DL
PRINT '*',0EH
LOOP AGAIN2
MOV CX, 79
AGAIN3:
DEC DL
MOVTO DH, DL
PRINT '*',0EH
LOOP AGAIN3
MOV CX, 24
AGAIN4:
DEC DH
MOVTO DH, DL
PRINT '*',0EH
LOOP AGAIN4
POP DX
POP CX
POP AX
RET
SHUCHU_K ENDP
;************************************************
;输出提示信息***********************************
SHUCHU_TISHI PROC
MOV DH, 2
MOV DL, 23
OUTPUT MSG13, 10, DH, DL
MOV DH, 5
MOV DL, 18
OUTPUT MSG0, 11, DH, DL
ADD DH, 2
SUB DL, 5
OUTPUT MSG1, 12, DH, DL
ADD DH, 8
ADD DL, 5
OUTPUT MSG2, 13, DH, DL
ADD DH, 2
ADD DL, 3
OUTPUT MSG3, 14, DH, DL
ADD DH, 2
ADD DL, 3
OUTPUT MSG4, 15, DH, DL
ADD DH, 2
ADD DL, 4
OUTPUT MSG14, 9, DH, DL
RET
SHUCHU_TISHI ENDP
;****************************************
;发声*************************************
SOUND PROC
PUSH AX
PUSH CX
IN AL, 61H
AND AL, 11111101B
OUT 61H, AL
MOV CX, 10000
AGAIN_S:
XOR AL, 2
OUT 61H, AL
CALL DELAY
LOOP AGAIN_S
POP CX
POP AX
RET
SOUND ENDP
DELAY PROC ;延时
PUSH CX
MOV CX, 0FFFH
NEXT_D: NOP
LOOP NEXT_D
POP CX
RET
DELAY ENDP
;*******************************************
;将2进制数转换成10进制数********************
CHANGE PROC
DSEG SEGMENT
BUF DB 7 DUP(?)
DSEG ENDS
PUSH BX
PUSH DX
PUSH SI
PUSH CX
LEA SI, BUF
PLUS: MOV BX, 10
MOV CX, 0
LOP1: MOV DX, 0
DIV BX
PUSH DX
INC CX
OR AX, AX
JNE LOP1
LOP2: POP AX
CMP AL, 10
JB L1
ADD AL, 7
L1: ADD AL, 30H
MOV [SI], AL
INC SI
DEC CX
JNE LOP2
MOV [SI], BYTE PTR '$'
LEA DX, BUF
MOV AH, 9
INT 21H
POP CX
POP SI
POP DX
POP BX
RET
CHANGE ENDP
;****************************************
;***********时间*************************
TIME PROC
PUSH AX
PUSH DX
MAIN:
MOV AH, 2
INT 1AH
CMP DH, SECONT
JNE GET
JMP NEXT
GET:
MOV SECONT, DH
INC COUNT3
MOV AX, COUNT3
CMP AX, 60
JNE NEXT3
MOV COUNT3, 0
INC COUNT4
MOV AX, COUNT4
CMP AX, 60
JNE NEXT4
MOV COUNT4, 0
INC COUNT5
NEXT3:
NEXT4:
MOV DH, 20
MOV DL, 27
PUSH DX
OUTPUT MSG11, 10,DH, DL
POP DX
MOVTO DH, DL
MOV AX, COUNT5
CALL CHANGE
MOV AH, 2
MOV DL, ':'
INT 21H
MOV AX, COUNT4
CALL CHANGE
MOV AH, 2
MOV DL, ':'
INT 21H
MOV AX, COUNT3
CALL CHANGE
NEXT:
POP DX
POP AX
RET
TIME ENDP
;*********************************************
;*******************************************
CSEG ENDS
END START ; set entry point.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -