1、用汇编编写的指法打字练习软件TTInit_boarder macro row,col,char,dhdl,count Local l1 mov cx,count mov dh,row mov dl,col l1:mov ah,02h mov bh,00h int 10h push cx mov ah,0ah mov al,char mov bh,00h mov cx,01h int 10h pop cx inc dhdl loop l1endmclear_screen macro top,left,bottom,right,col;清屏宏定义 mov ah,06h mov al,00h mov
2、 bh,col mov ch,top mov cl,left mov dh,bottom mov dl,right int 10hendm setcusor macro page,row,column;设置光标位置 mov ah,02h mov bh,page mov dl,column mov dh,row int 10hendm menu macro row,col,text;菜单显示宏定义 mov ah,02h mov bh,00h mov dh,row mov dl,col int 10h mov cx,0 mov ah,09h lea dx,text int 21h endm dat
3、a segment ; add your data here! ;pkey db press any key.$ kaishi db welcome to play the game! $ mes0 db =$ mes1 db 1.start game $ mes2 db 2.select $ mes3 db 3.exit $ mes4 db =$ mes5 db select num of menu:$ mes12 db =$ mes13 db 1.100 letters $ mes14 db 2.200 letters $ mes15 db 3.300 letters $ mes17 db
4、 =$ mes18 db Correct Rate:$ mes7 db press any key to start the game. $ mes8 db press esc key return main menu $ mes10 db Select The Letters Num $ mes19 db wait. $ mes11 db when the game was over,press enter to restart$ mes9 db Used Time:$ mes6 db The correct number:$ col db 00h,24h,0fdh,0dh;颜色 num d
5、w ? ;以输入字母的个数 numb dw ? ;输入正确字母的个数 score dw ? ;每轮游戏的分数 grade dw ? sum dw ? n db 26 letters db 500 dup(0) hour db 0 minu db 0 seco db 0 endsstack segment dw 128 dup(0)endscode segmentstart:; set segment registers: mov ax, data mov ds, ax mov es, ax ; add your code here ;clear_screen 0d,0d,24d,79d,07h
6、 Frame1: clear_screen 0d,0d,24d,79d,1eh ;清屏 Init_boarder 0d,0d,*,dl,80d ;显示边框上一排星号 Init_boarder 24d,0d,*,dl,80d ;显示边框下一排星号 Init_boarder 0d,0d,*,dh,25d ;显示边框左一排星号 Init_boarder 0d,79d,*,dh,25d ;显示边框右一排星号 menu 5d,20d,mes0 menu 6d,26d,kaishi ;显示菜单 menu 8d,30d,mes1 menu 10d,30d,mes2 menu 12d,30d,mes3 men
7、u 13d,20d,mes4 menu 14d,20d,mes5 inputMenuNum: mov ah,7 ;输入功能号,无回显 int 21h cmp al,1 je call num1 cmp al,2 je call num2 cmp al,3 je end1 jmp inputMenuNum ;输入不符要求重输 Frame2 proc mov dl,al ;将选择的功能号显示出来 mov ah,2 int 21h clear_screen 1d,1d,23d,78d,1eh ;清屏,边框还存在 menu 9d,20d,mes7 menu 11d,20d,mes8 ; menu 12
8、d,30d,mes10 menu 13d,20d,mes11 mov cx,2000h ;隐藏光标 mov ah,01h ;设置光标大小 int 10h mov ah,7 ;无回显输入字符 int 21h mov cx,1010h ;显示光标 mov ah,01h int 10h ret Frame2 endpnum1 proc mov dl,al ;将选择的功能号显示出来 mov ah,2 int 21h clear_screen 1d,1d,23d,78d,1eh;清屏,但边框存在 menu 9d,20d,mes7 menu 11d,20d,mes8 ;menu 12d,30d,mes10
9、 menu 13d,20d,mes11 mov cx,2000h ;隐藏光标 mov ah,01h int 10h mov ah,7 ;无回显输入字符 int 21h mov cx,1010h ;显示光标 mov ah,01h int 10h mov num,100 call play retnum1 endp num2 proc mov dl,al ;将选择的功能号显示出来 mov ah,2 int 21h clear_screen 1d,1d,23d,78d,1eh;清屏 menu 7d,20d,mes10 menu 8d,20d,mes12 menu 10d,20d,mes13 menu
10、 11d,20d,mes14 menu 12d,20d,mes15 menu 14d,20d,mes17 menu 15d,20d,mes5 inputMenuNum1: mov ah,07h int 21h cmp al,1 jz m1 cmp al,2 jz m2 cmp al,3 jz m3 cmp al,27 ;当输入esc键时退到主菜单 jz Frame1 jmp inputMenuNum1 m1: call Frame2 mov num,100 ;设置字符串个数为100 call play jmp m4 m2: call Frame2 mov num,200 call play j
11、mp m4 m3: call Frame2 mov num,300 call play jmp m4 m4: ret num2 endp play proc mov numb,0 ;正确字符个数 clear_screen 02d,02d,23,78,1eh ;清屏(边框还存在) lea si,letters mov bx,0 call getletter ;调用生成字符串子程序 menu 20d,15d,mes19 setcusor 0d,3d,10d ;设置光标位置 clear_screen 02d,02d,23,78,1eh ;清屏(边框还存在) call outletter setcus
12、or 0d,4d,10d ;设置光标位置 mov ah,2ch ;获取当前时间 int 21h mov hour,ch ;获取的小时放入hour中 mov minu,cl ;获取的分钟放入minu中 mov seco,dh ;获取的秒钟放入seco中 call inputletter menu 20d,5d,mes9 call counttime call outtime menu 20d,25d,mes6 mov ax,numb call PRINTAX menu 20d,50d,mes18 call CorrectRate input_quit: mov ah,07h int 21h cm
13、p al,27 jz Frame1 cmp al,0dh jz call play jmp input_quit ret play endp ;*;实现随机产生字符串 getletter proc output_letter: mov ah,2ch ;获取时间 ch为小时,cl为分,dh为秒,dl为1%秒 int 21h mov al,dl ;将1%秒放入al中 mov ah,0 ;将ah置0,ax当被除数 div n ;n为26,将商放到al中,将余数放入ah中 mov dl,ah ;将余数放入dl中 add dl,61h ;a的ascii码为61,将余数加上61得到随机产生字母的ascii
14、码 mov si,dl ;将随机产生的字符放入到letters中 inc si ;letters的偏移量加1 inc bx call DELAY ;计数量加1 cmp bx,num ;将已产生的字符量与所需产生的字符数比较 jnz output_letter ;当小于所需产生的字符数时,跳转至output_letter mov si,$ ;字符串结束 ret getletter endp ;*;实现字符串的换行输出outletter proc lea si,letters ;获取letters的首地址 again: mov dl,si ;将字符串相应偏移地址里的字符放入dl中 mov ah,0
15、2h ;显示字符 int 21h inc si ;letters偏移地址加1 cmp si,$ ;判断是否已经到字符串的末尾 jz q2 ;当已到达字符串末尾时跳转至q2,反之顺序执行 mov ah,03h ;获取光标当前位置 dh=行号,dl=列号 mov bh,0 int 10h cmp dl,75d ;判断光标列号是否为75,即已到达改行末尾 jz q1 ;当光标列号是为75跳转至q1 jmp again q1: add dh,2d ;将当前光标行号加2,实现隔行输出 setcusor 0d,dh,10d ;重新设定光标位置 jmp again q2: retoutletter endp
16、 inputletter proc lea si,letters ;获取字符串的首地址mov cx,num ;将字符串的长度放入cx中input: push cx ;将cx压栈 mov ah,03h ;获取光标当前位置 dh=行号,dl=列号 mov bh,0 ;页号为0 int 10h cmp dl,75d ;将光标当前列号与75作比较 jz l5 ;当光标当前列已是75则跳转到l5 l6: mov ah,7 ;输入字符无回显,al接收输入字符的ascii码 int 21h cmp al,08h ;判断输入键是否为退格键(退格键ascii码为08h) je l3 ;当输入退格键跳转至l3,若
17、不是则往下执行 cmp al,27 ;判断输入键是否为esc键 (esc键ascii码为27h) je quit ;当输入的是esc键,跳转至qiut,若不是则往下执行 cmp al,si ;将输入字符与letters里相应字符比较 je l1 ;当相等时跳转至l1,反之往下执行 jne l2 ;当输入的字符与letters里相应字符不相等,跳转至l2 done: mov dl,al ;将输入的字符放入dl中 mov ah,2 ;输出字符 int 21h inc si ;letters的偏移量加1 pop cx dec cx jnz input jmp l4 l1: add numb,1 ;输
18、入的字符正确,记录输入输入正确个数的numb加1 mov ah,09H ;在当前光标位置显示字符,不改变光标位置 mov bh,0H mov bl,2fh ;背景颜色为绿色 mov cx,1 int 10H jmp done l2: call SOUND ;输入错误 mov ah,09H ;在当前光标位置显示字符,不改变光标位置 mov bh,0H mov bl,4fh ;Z表示颜色。 mov cx,1 int 10H jmp done l3: mov ah,03h ;获取光标当前位置 dh=行号,dl=列号 mov bh,0 ;页号为0 int 10h cmp dh,4d ;判断当前光标输入
19、字符串的第一行 ja del1 ;当不在输入字符串的第一行,跳转到del1 cmp dl,11 jb del sub dl,1 ;将光标后退一格 setcusor bh,dh,dl dec si pop cx inc cx push cx del: mov ah,08h ;读取当前光标位置的字符及属性 mov bh,0 int 10h cmp ah,2fh ;判断字符属性颜色是否为绿色 jz l8 ;当字符属性颜色为绿色时跳转至l8 l9: ;将需删除的字符用空格代替,并将背景色改为蓝色实现删除 mov al,20h ;将空格键的ascii码放入al中 mov ah,09H ;在当前光标位置显
20、示字符,不改变光标位置 mov bh,0H ;页号为0 mov bl,1eh ;将要显示的背景颜色蓝色放入bl中 mov cx,1 ;循环次数为1 int 10H pop cx ;循环次数出栈 jmp input ;继续输入 l5: add dh,2d ;将当前光标的行增加2 setcusor 0d,dh,10d ;重新设置光标位置,实现隔行换行 jmp l6 ;跳转至l6继续执行 del1: dec si ;letters的偏移地址减1 pop cx ;将循环计数器的内容出栈 inc cx ;循环次数加1 push cx ;将cx入栈 cmp dl,10 ;将光标当前所在列与10比较 jz
21、l7 ;当光标当前所在列为10,跳转至l7 sub dl,1 ;将光标后退一格 setcusor bh,dh,dl jmp del l7: sub dh,2 ;将光标的行号减2 setcusor bh,dh,74d ;重新设置光标的位置,实现退格时的隔行退格 jmp del ;跳转至del l8: sub numb,1 ;将记录的正确个数减1 jmp l9 ;跳转至l9 quit: jmp Frame1 ;显示主菜单 l4: ret inputletter endp;*;计算所用时间功能 counttime proc mov ah,2ch int 21h cmp dh,seco jb t1 s
22、ub dh,seco mov seco,dh sec:cmp cl,minu jb t2 sub cl,minu mov minu,cl min:cmp ch,hour jb t3 sub ch,hour mov hour,ch hou:jmp t4 t1:add dh,60d sub dh,seco mov seco,dh cmp cl,1 jb t11 tt:sub cl,1 jmp sec t11:add cl,60d sub ch,1 jmp tt t2: add cl,60 sub cl,minu mov minu,cl sub ch,1 jmp min t3: add ch,24
23、;sub ch,hour jmp hou t4:ret counttime endp ;*;将时间显示出来 outtime proc ;显示时间 mov al, hour mov ah,0 call PRINTAX mov dl,: int 21h mov al,minu mov ah,0 call PRINTAX mov dl,: int 21h mov al,seco mov ah,0 call PRINTAX retouttime endp ;发声*SOUND PROC push dx ;将dx压栈 push ax ;将ax压栈 mov dl,7 ;将响铃符ascii码放入dl中 mov
24、 ah,2 ;显示字符功能 int 21h pop ax ;将ax出栈 pop dx ;将dx出栈 RETSOUND ENDP ;*;将16进制转化为十进制并输出PRINTAX PROC ;以10进制输出AX中的无符号整数. MOV BX, 10 ;按10进制输出. OR AX, AX JZ _0_LOOP_P: XOR DX, DX DIV BX ;除法,DX放余数,AX放商 MOV CX, AX ;商. OR CX, DX JZ _E_ ;若商与余数都为0则结束递归. PUSH DX ;保存DX中的余数. CALL LOOP_P ;递归. POP DX ;恢复余数. ADD DL, 0 ;
25、变成ASCII码. JMP _1_ _0_: MOV DL, 0 ;是0则直接输出. _1_: MOV AH, 2 INT 21H _E_: RET PRINTAX ENDP;*;实现延时功能 DELAY proc near push cx push ax push dx mov cx,0FFFFH D0:mov ax,0FFFFH D1: mov dx,2000 D2: dec dx jnz D2 dec ax jz D1 dec cx jnz D0 pop dx pop ax pop cx retDELAY endp ;*;实现正确率计算CorrectRate proc push ax mov ah,0 mov al,100 mul numb div num call PRINTAX mov dl,25h mov ah,02h int 21h pop ax ret CorrectRate endp end1: mov ax, 4c00h ; exit to operating system. int 21h ends
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2