一、设计目的
本次课程设计的目的主要是将课堂上所学的知识学以致用,加深对课本知识的了解。了解和掌握汇编语言程序设计过程、方法及实现,为以后学微机原理打下良好的基础,增强对汇编语言的认识,掌握汇编语言的中断调用功能的应用,可以用汇编语言调用各种中断调用功能,通过课程设计可以使我们更加了解书上的知识,了解书上的语句并且能够应用自己的程序中。
二、设计任务
在DOS环境中编程完成以下任务:
将26个字母中的任一字母从屏幕下落,用户要在这个过程中输入落下的字母,如果输入正确,字母消失;输入不正确,字母继续下落。要求设计主菜单:按回车键进入打字练习;按ESC键返回主界面;按空格暂停;按大写字母“E”程序结束
三、设计思想
用汇编语言实现打字程序的思想,首先用BIOS的10H中断类型的09H号功能(在当前光标位置显示字符,不改变光标位置,输入字符:AL=字符 BH/BL=页号/属性 CX=重复次数),显示一个有提示信息的开始界面。调用DOS系统功能调用的一号功能,接受从键盘输入的字符到AL寄存器,如果(AL)为空格,进入打字练习界面;如果(AL)为“E”,则退出程序。在界面的第0行显示由26个字母组成的字符串。字母下落的设计过程是:
1. 利用BIOS功能调用的2号功能,设置光标位置。
2. 利用BIOS功能调用的10H号功能在光标位置写字母。
3. 延迟一段时间。
4. 重置光标位置(列坐标不变,改变行坐标),利用10号功能在光标位置写空格,延迟一段时间。
5. 重复(1)—(4)。
打字练习实现过程:当字母下落没有超过最大行坐标时,利用 DOS系统功能调用的6号功能,接受从键盘输入的字符到AL寄存器。如果(AL)为1BH(Esc),则转向主界面显示的程序段:如果(Al)为空格,则字母在确定光标的位置显示,延迟一段时间,直到(AL)再次为空格;如果(AL)为任一字母,则判断其是否和下落字母相同,如果相同,则在相应光标位置显示空格;否则,字母继续下落。重复以上过程。
编好程序最后,把该程序编译成testword.exe格式,然后运行该程序,出现在菜单的主界面,按空格键出现由26个字母组成的乱顺序行,这时其中任一字母下落,在键盘上输入该字母,如果事输入正确,字母消失;否则字母继续下落。按Esc健则返回主菜单;按空格键暂停:按“E”退出。
四、程序代码
;初始化宏定义
Init_game macroop1,op2,op3,op4,op5,op6 ;循环输出,用于初始化界面
mov cx,00h
mov dh,op1 ; 起行
mov dl,op2 ;起列
op6: mov ah,02h
mov bh,00h
int 10h
push cx
mov ah,0ah
mov al,op3 ; 要显示的字符
mov bh,00h
mov cx,01h
int 10h
pop cx
inc cx
inc op4 ;指出循环输出的是行还是列
cmp cx,op5 ;循环次数
jne op6
endm
;清屏宏定义
clear_screen macroop1,op2,op3,op4
mov ah,06h
mov al,00h
mov bh,07h
mov ch,op1
mov cl,op2
mov dh,op3
mov dl,op4
int 10h
mov ah,02h
mov bh,00h
mov dh,00h
mov dl,00h
int 10h
endm
;菜单显示宏定义
menu macro op1,op2,op3
mov ah,02h
mov bh,00h
mov dh,op1
mov dl,op2
int 10h
mov ah,09h
lea dx,op3
int 21h
endm
data segment
ZK db "WELCOME TO PLAY$" ;分隔符
meg db "press Enter key tocontinue.......$"
meg1 db "when a letter isdropping,please hit it!$" ;主界面上 的内容
meg2 db "press space key topause!$"
meg3 db "press ESC key toreturn main interface!$"
meg4 db "press letter 'E'to exit!$"
speed dw 2900d
letters db"jwmilzoeucgpravskntxhdyqfb"
db "iytpkwnxlsvxrmofzhgaebudjq"
db "nwimzoexrphysfqtvdcgljukda"
letters_bak db"jwmilzoeucgpravskntxhdyqfb"
db"iytpkwnxlsvxrmofzhgaebudjq"
db"nwimzoexrphysfqtvdcgljukda"
letter_counter db 0
life_flag db 78 dup(0)
position_flag db 78 dup(0)
present_position db 1
data ends
stack segment parastack 'stack'
db 64 dup(0)
stack ends
code segment
main proc far
assumecs:code,ds:data,ss:stack
start: mov ax,data
mov ds,ax
mov letter_counter,00h
mov present_position,1
lea si,position_flag
mov ah,00h
mov cx,00h
init_postion_flag:mov [si],ah
inc si
inc cx
cmp cx,78d
jne init_postion_flag
lea di,letters
lea si,letters_bak
mov cx,00h
init_letters: mov ah,[si]
mov [di],ah
inc si
inc di
inc cx
cmp cx,78d
jne init_letters
mov ah,00h
lea si,life_flag
mov cx,00h
init_life_flag: mov [si],ah
inc si
inc cx
cmp cx,78d
jne init_life_flag
mov cx,00h
mov ah,01h
or ch,00010000b
int 10h
clear_screen 00d,00d,24d,79d
Init_game00d,00d,0ah,dl,80d,nextsign1
Init_game 24d,00d,0ah,dl,80d,nextsign2
Init_game00d,00d,0ah,dh,25d,nextsign3
Init_game00d,79d,0ah,dh,25d,nextsign4
;菜单信息宏调用
menu 05d,15d,ZK
menu 07d,15d,meg
menu 09d,15d,meg1
menu 11d,15d,meg2
menu 13d,15d,meg3
menu 15d,15d,meg4
put: mov ah,02h ; 设置光标位置
mov bh,00h
mov dh,22d
mov dl,33d
int 10h
again: mov ah,01h ; 从键盘输入任一字符
int 21h
cmp al,0dh
je speed3
cmp al,45h
je exit
cmp al,65h
je exit
jmp again
exit: mov ah,4ch ;返回Dos
int 21h
speed3: mov ax,speed+12
mov speed,ax
jmp begin
;清屏宏调用
begin: clear_screen 01d,01d,23d,78d
clear_screen 01d,01d,23d,78d
Init_game23d,01d,01h,dl,78d,nextsign5
mov ah,02h
mov bh,00h
mov dh,01h
mov dl,01h
int 10h
mov cx,00h
lea si,letters
nextletter: mov ah,02h ;显示字母
mov dl,[si]
int 21h
inc si
inc cx
cmp cx,78d
je nextcycle
jmp nextletter
from_front: sub present_position,78d
jmp gobackto_si
find_zero: cmp letter_counter,78d
je recycle
cmp present_position,78d
je from_one
mov ah,00h
nextsi: add present_position,01h
inc si
cmp [si],ah
je gobackto_di
cmp present_position,78d
je from_one
jmp nextsi
from_one: mov present_position,01h
jmp gobackto_si
recycle: mov letter_counter,00h
mov present_position,01d
lea si,position_flag
mov cx,00h
mov ah,00h
clearsi: mov [si],ah
inc cx
cmp cx,78d
je nextcycle
inc si
jmp clearsi
nextcycle: lea di,letters
lea si,position_flag
add present_position,31d
cmp present_position,78
ja from_front
gobackto_si: add si,word ptrpresent_position
dec si
mov ah,[si]
cmp ah,01h
je find_zero
gobackto_di: mov ah,01h
mov [si],ah
add di,word ptrpresent_position
dec di
mov dl,present_position
mov ah,02h
mov bh,00h
mov dh,01h
int 10h
mov cx,00h
nextrow: push cx
mov cx,00h
out_cycle: push cx 延迟
mov cx,00h
in_cycle: add cx,01h
cmp cx,1000
jne in_cycle
push dx
mov ah,06h ;从键盘输入字符
mov dl,0ffh
int 21h
pop dx
jz pass
cmp al,1bh
;如果输入Esc,则返回主菜单
je to_start1
cmp al," "
;如果输入空格,则暂停
je pause
cmp al,[di]
;如果输入字母正确!则字母消失
je disappear
pass: pop cx
inc cx
cmp cx,speed
je print
jmp out_cycle
pause: push dx ;暂停处理
mov ah,06h
mov dl,0ffh
int 21h
pop dx
cmp al," "
jne pause
jmp pass
to_start1: jmp start ;返回主菜单
print: mov ah,0ah
mov al," "
mov bh,00h
mov cx,01h
int 10h
inc dh
mov ah,02h ;改变光标位置
mov bh,00h
int 10h
mov ah,0ah ;在当前光标位置写字母
mov al,[di]
mov bh,00h
mov cx,01h
int 10h
pop cx
inc cx
cmp cx,21d
je print_next_letter
jmp nextrow ;下一行
disappear: pop cx ;击中字母后输出空格
pop cx
mov ah,0ah
mov al,""
mov bh,00h
mov cx,01h
int 10h
jmp hit
print_next_letter: leasi,life_flag
add si,word ptrpresent_position
dec si
mov ah,0ah
mov al," "
mov bh,00h
mov cx,01h
int 10h
inc dh
mov ah,02h
mov bh,00h
int 10h
mov ah,0ah
mov al," "
mov bh,00h
mov cx,01h
int 10h
mov ah,1
mov [si],ah
hit: mov ah,02h
mov bh,00h
mov dh,01h
mov dl,present_position
int 10h
;出现下一个字母的算法
mov al,[di]
add al,7
cmp al,7ah
ja convey_letter
mov ah,0ah
mov bh,00h
mov cx,01h
int 10h
mov [di],al
add letter_counter,01h
jmp nextcycle
convey_letter: sub al,7ah
add al,61h
mov ah,0ah
mov bh,00h
mov cx,01h
int 10h
mov [di],al
add letter_counter,01h
jmp nextcycle
clear_screen 01,01,23,78
mov ah,02h
mov bh,00h
mov dh,11d
mov dl,20d
int 10h
inc dh
inc dh
mov ah,02h
mov bh,00h
int 10h
notkey: mov ah,07h
int 21h
cmp al,0dh
je to_start
cmp al,1bh
je over
jmp notkey
to_start: clear_screen 00,00,24,79
jmp start
over: clear_screen 01,01,23,78
mov ah,02h
mov bh,00h
mov dh,11d
mov dl,15h
int 10h
mov ah,02h
mov bh,00h
mov dh,13d
mov dl,15h
int 10h
mov ah,07h
int 21h
mov ah,07h
int 21h
clear_screen 00,00,24,79
mov ax,4c00h
int 21h
main endp
code ends
end start