?? type1.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 + -