本题目是基于汇编语言完成的一个较为简单的电话本程序,能够实现插入信息(包括姓名和号码),查询信息(分为通过姓名查询和通过号码查询),显示所有联系人信息,数据导出到文本文件,显示帮助文档,显示版权信息,修改背景颜色,字体颜色,有较友好的开机界面(可显示系统时间),退出程序时可以播放音乐。
写了一个周末的报告交上去,老贺还没时间看,也不知道能不能给过😔 ...
运行代码还需要几个文件(全部放到masm文件夹里):
放云盘的链接总是失效(就离谱),真想要可以qq私聊我。
效果展示
程序运行成功,首先显示欢迎界面(包括欢迎语和系统时间):
5秒动画之后进入主界面:
通过下面的提示用户可选择相应的功能(0~7):
按下数字1,进行创建联系人(包括姓名和电话号),并高亮显示选择的指令:
按下回车,显示创建成功的提示语:
再次按下回车返回主界面:
此时按下数字2选择进行联系人姓名查找,输入姓名(高亮选择):
查询成功将显示联系人姓名及手机号
输入不存在的联系人姓名会显示查找失败:
按下数字3进行根据电话号进行查找联系人(高亮显示选择):
查找成功将会显示:
输入不存在的手机号显示查找失败:
输入数字4显示所有联系人及其电话号:
输入数字5导出电话簿到文件
输入数字6显示版权信息:
输入数字7显示帮助:
输入数字0(高亮显示),输入1~3中的一个选择想演奏的音乐,演奏结束退出电话簿:
按F1改变界面及字体颜色:
所有功能实现完毕。
代码:
title phonebook(exe) .model small .stack 4096 .data toprow equ 05 ;菜单上边行 botrow equ 15 ;菜单底边行 leftcol equ 23 ;菜单左边列 len_line equ 36 ;菜单行的长度 attrib db ? ;屏幕属性 col db 00 ;屏幕列 row db 00 ;屏幕行 shadow db 36 dup(0dbh) ;阴影符 menu db 0c9h, 34 dup(0cdh),0bbh db 0bah, ' Menu ', 0bah db 0bah, ' 1.Create a new contact. ', 0bah db 0bah, ' 2.Find contacts by name. ', 0bah db 0bah, ' 3.Find contacts by number. ', 0bah db 0bah, ' 4.Show all existing contacts. ', 0bah db 0bah, ' 5.Export the phone book. ', 0bah db 0bah, ' 6.About this phone book. ', 0bah db 0bah, ' 7.How do I use it? ', 0bah db 0bah, ' 0.Exit the phone book. ', 0bah db 0c8h, 34 dup(0cdh), 0bch prompt db 'Please select the number from 0 to 7!' table dw exit,new,find_name,find_num,display,export,about,help ;直接定址表查询 song dw song_1,song_2,song_3 storage db 20 dup(15 dup(0),15 dup(0)) ;存放电话簿内容 name_buff db 15,?,15 dup(?) ;姓名缓冲区 num_buff db 15,?,15 dup(?) ;电话号码缓冲区 sum db 0 nam db 10,13,'Please enter a contact name:','$' num db 10,13,'Please enter a contact phone number:','$' suc db 10,13,'New Contact Created!','$' err db 10,13,'Sorry, no related information was found.','$' emp db 10,13,'The phone book is empty, maybe you should create a new friend.','$' fie db 10,13,'An error occurred in the file operation.','$' fis db 10,13,'The phonebook was exported successfully. please check.','$' son db 10,13,'Let me sing a parting song for you, and we will see you next time! ! !' db 10,13,'1 is Jasmine, 2 is Farewell ,3 is Those Flowers.','$' filename db 'phone book.txt',0 ;保存文件名 handle dw ? ;保存句柄 kmlj db 28 dup(0),' Welcome To Use ' ;打开的界面 db 0ah,0dh,28 dup(0),'Telephone Book \(^_^)/','$' ;标题 about_ db 25 dup(0),0dah,28 dup(0c4h),0bfh ;关于界面显示 db 0ah,0dh,25 dup(0),0b3h,'Version: ',0b3h ;版本 db 0ah,0dh,25 dup(0),0b3h,' Telephone Book \(^_^)/ ',0b3h ;标题 db 0ah,0dh,25 dup(0),0b3h,'Copyright(c)2020.5 LMW ',0b3h ;日期时间 db 0ah,0dh,25 dup(0),0c0h,28 dup(0c4h),0d9h,'$' help_ db 28 DUP(0),'Telephone Book \(^_^)/' ;使用说明 db 0ah,0dh,37 dup(0),'Help' ;帮助 db 0ah,0dh,' Please take three minutes to read it. Believe me, my dear friend, you will benefit from a lifetime! ! !' db 0ah,0dh,' This application is to use assembly language to complete a very simple phone book program, ' db 'which can insert information (including name and number), query information (divided by name query and number query), ' db 'display all contact information, and export data to text Documents, modify the background color, font color, and, my love, it can also sing a song for you! ! !' db 0ah,0dh,' (1) Create a new contact. AOH, my favorite friend, do you also have many friends? Tell me their name and mobile phone number, let us share happiness together!' db 0ah,0dh,' (2) Find your friend by name. Ah, my friend, please don not tell me, dear, you have forgotten the name of your contact!' db 0ah,0dh,' (3) Find your friend by phone number. Although you forgot the name of the contact, dear, the phone number should always be remembered, I can help you find the name of the contact.' db 0ah,0dh,' (4) Honey, let us see how many friends you have made!' db 0ah,0dh,' (5) Save your friends (in the file), please do not lose it!' db 0ah,0dh,' (6) It does not matter who the author is, he is just a little transparent.' db 0ah,0dh,' (7) The climax comes, my favorite friend in the world, when you leave, let me sing a beautiful song for you, I hope that we will have a date! ! !','$' x1 db ? ;左下角坐标定义 y1 db ? ;右下角坐标定义 x2 db ? ;右上角坐标定义 y2 db ? ;左上角坐标定义 year db ?,?,?,?,'/' ;定义年的长度 month db ?,?,'/' ;定义月的长度 day db ?,?,'$' ;定义日的长度 hour db ?,?,':' ;定义小时的长度 minute db ?,?,':' ;定义分钟的长度 second db ?,?,'$' ;定义秒的长度 s db ?,?,'$' ;定义单位的长度 time_p db ? ;定义时间的长度 mus_frep1 dw 330,330,392,440,524,524,440 ;茉莉花的音符 dw 392,392,440,392,392 dw 330,330,392,440,524,524,440 dw 392,392,440,392,392 dw 524,524,524,440,524 dw 587,587,524,524 dw 440,392,440,524,440,392 dw 349,349,392,349,349 dw 440,392,349,440,392,440 dw 524,587,698,524,524 dw 392,440,524,392,440,349,294 dw 262,262,294,294,349 dw 392,440,349,392,349,294 dw 262,262,262,262,-1 mus_time1 dw 2 dup(50,6 dup(25),50,2 dup(25),2 dup(50)) ;茉莉花的发音频率 dw 3 dup(50),2 dup(25) dw 4 dup(50) dw 50,2 dup(25),50,2 dup(25) dw 50,2 dup(25),2 dup(50) dw 4 dup(25),75,25 dw 50,2 dup(25),2 dup(50) dw 50,6 dup(25) dw 3 dup(50),2 dup(25) dw 75,5 dup(25) dw 4 dup(50) mus_frep2 dw 392,330,392,524,524 ;送别的音符 dw 440,524,392,392 dw 392,262,294,330,294,262 dw 294,294,294,294 dw 392,330,392,524,494 dw 440,524,392,392 dw 392,294,330,349,247 dw 262,262,262,262 dw 440,524,524,524 dw 494,440,494,524,524 dw 440,494,524,440,440,392,330,262 dw 294,294,294,294 dw 392,330,392,524,494 dw 440,524,392,392 dw 392,294,330,349,247 dw 262,262,262,262,-1 mus_time2 dw 50,2 dup(25),2 dup(50) ;送别的发音频率 dw 4 dup(50) dw 50,2 dup(25),50,2 dup(25) dw 4 dup(50) dw 50,2 dup(25),75,25 dw 4 dup(50) dw 50,2 dup(25),75,25 dw 2 dup(4 dup(25)) dw 50,2 dup(25),2 dup(50) dw 8 dup(25) dw 4 dup(50) dw 50,2 dup(25),75,25 dw 4 dup(50) dw 50,2 dup(25),75,25 dw 4 dup(50) mus_frep3 dw 196,220,262,262,330,294,330,294,294,262 ;那些花儿的音符 dw 220,262,294,294,262,392,392 dw 196,220,262,262,294,330,262,440,440,392 dw 392,349,349,330,262,262,294,294 dw 349,330,262,262,330,394,330,262,262,294 dw 392,330,262,262,294,262,196,220,220 dw 262,220,196,196,330,294,262,294,294,294 dw 330,294,262,262,294,262,262 dw 392,330,294,330,262,262,294,294 dw 392,330,294,330,440,220,262,262 dw 196,220,262,262,330,294,294 dw 330,294,262,262,294,262,262 dw 440,392,392,392,392,440,440,392,392,392,392 dw 440,392,392,392,330,330,330,330 dw 294,262,262,262,392,294,330,330,294,294,392 dw 330,330,330,330,262,294,294,294,294 dw 440,392,392,392,392,440,440,392,392,392,392 dw 440,392,392,392,330,330,330,330 dw 294,262,262,262,220,196,220,262,262,330 dw 294,294,294,294,330,262,262 dw 392,330,294,330,262,262,294,294 dw 392,330,294,330,220,220,262,262 dw 196,220,262,262,330,294,294 dw 330,294,262,262,294,262,262,-1 mus_time3 dw 50,2 dup(25),2 dup(50),50,2 dup(25),2 dup(50) ;那些花儿的发音频率 dw 50,2 dup(25),2 dup(50),2 dup(100) dw 50,2 dup(25),2 dup(50),50,2 dup(25),2 dup(50) dw 2 dup(50),50,2 dup(25),2 dup(50),100 dw 50,2 dup(25),2 dup(50),50,2 dup(25),2 dup(50) dw 50,2 dup(25),2 dup(50),2 dup(25),50,100 dw 50,2 dup(25),2 dup(50),50,2 dup(25),2 dup(50) dw 50,2 dup(25),2 dup(50),2 dup(100) dw 2 dup(2 dup(50),50,2 dup(25),2 dup(50),100) dw 2 dup(50,2 dup(25),2 dup(50),2 dup(100)) dw 50,2 dup(25),25,50,25,50,2 dup(25),25,75 dw 50,2 dup(25),25,50,25,2 dup(100) dw 50,3 dup(25),50,25,50,2 dup(25),2 dup(50) dw 50,6 dup(25),2 dup(100) dw 50,2 dup(25),25,50,25,50,2 dup(25),25,75 dw 50,2 dup(25),25,50,25,2 dup(100) dw 2 dup(50,2 dup(25),2 dup(50)) dw 50,2 dup(25),2 dup(50),2 dup(100) dw 2 dup(2 dup(50),50,2 dup(25),2 dup(50),100) dw 2 dup(50,2 dup(25),2 dup(50),2 dup(100)) .386 .code ;---------------------------------------------------------------- ; 宏定义:point | ; 功能:设置光标位置 | ; 入口参数:hang,lie | ; 出口参数:ah,bh,d | ;---------------------------------------------------------------- point macro hang,lie ;设置光标位置 push ax ;保存cpu现场 push bx push cx push dx mov ah,2 ;设置光标 mov bh,0 ;设置第0页 mov dh,hang ;设置第hang行 mov dl,lie ;设置第lie列 int 10h pop dx ;恢复cpu现场 pop cx pop bx pop ax endm ;---------------------------------------------------------------- ; 宏定义:htos | ; 功能:将十进制的每一位转为ascll | ; 入口参数:shu,string | ; 出口参数:string | ;---------------------------------------------------------------- htos macro shu,string ;提示输入字符串 push ax ;保存cpu现场 push bx push cx push dx mov bl,0ah ;除以十 mov al,shu ;保存被除数 mov ah,0 ;因为是ax做被除数,所以高位要置0 div bl ;除法进行转化 add ah,30h ;余数转ascll mov string+1,ah ;完成第二位的转化 mov ah,0 ;恢复ah进行下一次运算 div bl ;除法进行转化 add ah,30h ;向右移30h的位置 mov string,ah ;完成第一位的转化 pop dx ;恢复cpu现场 pop cx pop bx pop ax endm ;---------------------------------------------------------------- ; 宏定义:show | ; 功能:显示label为偏移地址以$结尾到屏幕 | ; 入口参数:label | ; 出口参数:无 | ;---------------------------------------------------------------- show macro label ;显示宏定义 lea dx,label ;取文件路径地址 mov ah,9 ;使用21h中断的的显示字符串功能 int 21h endm ;---------------------------------------------------------------- ; 宏定义:input | ; 功能:输入数据到缓冲区 | ; 入口参数:opr1 | ; 出口参数:无 | ;---------------------------------------------------------------- input macro opr1 ;输入及处理缓冲区数据宏定义 local s0 ;多次调用定义为局部变量 lea dx,opr1 mov ah,10 int 21h ;21号中断的10号功能,输入字符串到缓冲区,回车结束输入 mov bh,0 mov bl,opr1+1 ;用bl存放从键盘输入的字符串长度 mov cx,15 sub cx,bx ;计算剩下的长度 s0: mov opr1[bx+2],20h ;剩下的地方补空格ascll为20h inc bx loop s0 endm ;---------------------------------------------------------------- ; 宏定义:save | ; 功能:保存数据到存储区 | ; 入口参数:opr2,op3 | ; 出口参数:无 | ;---------------------------------------------------------------- save macro opr2,opr3 ;缓冲区数据保存导数据区宏定义 lea di,storage mov ax,@data ;采用串传送的方法 mov es,ax ;ds:si传到es:di mov ah,0 mov al,sum ;ax保存现存联系人总数 mov bl,30 mul bl add di,ax ;当前存储条数*30,得到新姓名起始地址 add di,opr2 ;di+0是保存姓名,di+15是保存手机号的位置 lea si,opr3+2 ;因为从第三个字节开始存储数据,让偏移地址加2 cld mov cx,15 rep movsb ;串传送以字节为单位 endm ;---------------------------------------------------------------- ; 宏定义:find | ; 功能:根据姓名/电话号查询 | ; 入口参数:opr4,op5 | ; 出口参数:无 | ;---------------------------------------------------------------- find macro opr4,opr5 ;查询/查找搜索并显示宏定义 local s3 local equal local s4 ;设置局部变量 lea di,storage+opr4 ;存储位置加0是姓名的位置,+15是电话号的位置 push di mov bh,0 mov bl,sum ;bx保存数据总数 mov ax,@data mov es,ax s3: lea si,opr5+2 ;因为从第三个字节开始存储数据,让偏移地址加2 mov cx,15 repe cmpsb ;串比较指令比较15个字符 jz equal ;标志寄存器确定字符比较成功跳转显示 pop di ;出栈的是保存的每一行的起始位置 add di,30 ;下一个姓名或电话号的位置 push di dec bx ;未匹配,找下一个 jnz s3 ;bx!=0重新匹配下一个 call cls point 1,4 show err ;总数比较完成还没退出说明查找失败 call far ptr ml ;返回主菜单 equal: call cls ;清屏显示 pop di ;姓名或电话号开始的位置 sub di,opr4 ;姓名开始的话-0,电话号开始的话-15为开始显示的位置 mov cx,30 ;查找成功进行显示 s4: mov dl,[di] mov ah,6h int 21h ;调用中断进行显示 inc di ;按字节显示 loop s4 call newline ;输出换行显示 pop cx call far ptr ml endm ;---------------------------------------------------------------- ; 宏定义:highlight | ; 功能:对选择的功能进行高亮显示 | ; 入口参数:opr6 | ; 出口参数:attrib | ;---------------------------------------------------------------- highlight macro opr6 mov attrib,1bh call e10display ;其他选项正常显示 mov row,toprow+opr6 ;确定选择的行 mov attrib,5fh ;选择行品红底亮白色显示 call e10display ;显示 endm ;---------------------------------------------------------------- ; 宏定义:address | ; 功能:确定音符和音频地址 | ; 入口参数:A,B | ; 出口参数:si,bp | ;---------------------------------------------------------------- address macro A,B lea si,A lea bp,ds:B endm ;---------------------------------------------------------------- ; 主程序:main | ; 功能:安装中断 | ; 入口参数: | ; 出口参数:无 | ;---------------------------------------------------------------- main proc far ;主程序开始 push cs ;ds与cs相同 pop ds mov ax,0 mov es,ax mov si,offset int9 ;安装定义中断 mov di,204h mov cx,offset int9end - offset int9 ;传送新中断 cld rep movsb push es:[9*4] ;将原中断地址保存在0:200单元处 pop es:[200h] push es:[9*4+2] pop es:[202h] cli ;改变后中断的入口地址 mov word ptr es:[9*4],204h mov word ptr es:[9*4+2],0 sti ;中断屏蔽寄存器 mov ax,@data ;保存数据段 mov ds,ax mov es,ax call be call cls call home main endp ;---------------------------------------------------------------- ; 主程序:home | ; 功能:主菜单 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- home proc near ;主菜单 a20: call cls ;清屏 ml: call c10menu ;显示阴影框和全部菜单 mov row,toprow+1 ;设置上部菜单项的行 mov attrib,5fh ;设置行为突出显示品红白 call e10display ;当前菜单行为高亮度 call c10input ;菜单选择 cmp al,1bh ;按下escape键? jne a20 ;否,继续 mov ax,0600h ;处理结束 call cls ;再次清屏 over: mov ax,0 mov es,ax push es:[200h] pop es:[9*4] ;恢复原中断地址 push es:[202h] pop es:[9*4+2] mov ax,4c00h ;结束程序 int 21h home endp ;---------------------------------------------------------------- ; 子程序:c10menu | ; 功能:显示阴影框和全部菜单 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- c10menu proc near mov ax,1301h ;请求显示,前移光标 mov bx,0060h ;棕底黑字 lea bp,shadow ;阴影符地址 mov cx,len_line ;行的长度 mov dh,toprow+1 ;屏幕行 mov dl,leftcol+1 ;屏幕列 c20: int 10h ;显示阴影 inc dh ;下一行阴影 cmp dh,botrow+2 ;全部行是否显示完 jne c20 ;否,重复 mov attrib,1bh ;蓝底浅青字 mov ax,1300h ;请求显示 mov bh,00 ;第0页 mov bl,attrib ;属性 lea bp,menu ;菜单地址 mov cx,len_line ;行的长度 mov dh,toprow ;屏幕行 mov dl,leftcol ;屏幕列 c30: int 10h ;显示菜单 add bp,len_line ;下一个菜单行 inc dh ;下一行 cmp dh,botrow+1 ;全部行显示完? jne c30 ;否,重复 mov ax,1301h ;请求显示 mov bh,00 ;0页 mov bl,attrib ;属性 lea bp,prompt ;提示行 mov cx,37 ;提示符长度 mov dh,botrow+3 ;屏幕行 mov dl,24 ;屏幕列 int 10h ;显示提示输入符 ret c10menu endp ;---------------------------------------------------------------- ; 子程序:c10input | ; 功能:进行输入选择调用子程序 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- c10input proc near pusha ;保护现场 b0: mov ah,10h int 16h ;从键盘输入 sub al,48 ;ascii转数字 cmp al,0 jb b0 cmp al,7 ja b0 ;确保输入的数在0-7之间 mov bl,al mov bh,0 add bx,bx ;x2才是真正的偏移地址 call word ptr table[bx] ;代码定址调用相应的子程序 mov ah ,10h int 16h ;再次从键盘输入 cmp al,0dh ;是否为回车,是就返回 jne b0 popa ret c10input endp ;---------------------------------------------------------------- ; 子程序:e10display | ; 功能:设置菜单行为(被选/未选) | ; 入口参数:row,menu,toprow,attrib | ; 出口参数:无 | ;---------------------------------------------------------------- e10display proc near movzx ax,row ;行扩展传送 sub ax,toprow ;找到当前显示的行 imul ax,len_line ;乘以行的长度 lea si,menu+1 ;选择的菜单行 add si,ax mov ax,1300h ;请求显示 mov bh,00 ;页和属性 mov bl,attrib mov bp,si ;字符串偏移地址 mov cx,len_line-2 ;串长度 mov dh,row ;行 mov dl,leftcol+1 ;列 int 10h ;显示 ret e10display endp ;---------------------------------------------------------------- ; 子程序:exit | ; 功能:退出系统并唱歌 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- exit proc near ;退出子程序 point 19,4 ;设置光标位置 highlight 9 ;高亮 show son ;显示选择 xuange:mov ah,10h int 16h ;键盘输入 sub al,48 ;ascii转数字 mov bl,al mov bh,0 add bx,bx call word ptr song[bx-2] ;代码定址表选择 song_1: ;茉莉花 address mus_frep1, mus_time1 jmp bye song_2: ;送别 address mus_frep2, mus_time2 jmp bye song_3: ;那些花儿 address mus_frep3, mus_time3 bye: call music ;演奏音乐 call over ;退出程序 exit endp ;---------------------------------------------------------------- ; 子程序:new | ; 功能:新建联系人 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- new proc ;新建联系人子程序 point 19,4 ;设置光标位置 highlight 2 ;高亮第二行 show nam input name_buff ;输入姓名到缓冲区 save 0,name_buff ;保存姓名到数据区 show num input num_buff ;输入电话号码到缓冲区,调用宏 save 15,num_buff ;保存电话号码到数据区,调用宏 call cls ;清屏 point 1,4 ;设置光标位置 show suc ;创建成功 inc byte ptr sum ;数据加一 ret ;子程序返回 new endp ;---------------------------------------------------------------- ; 子程序:find_name | ; 功能:根据姓名查找联系人 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- find_name proc ;根据姓名查找子程序 point 19,4 ;设置光标位置 highlight 3 ;高亮第三行 show nam input name_buff ;输入姓名到缓冲区 find 0,name_buff ;将缓冲区姓名与数据区进行匹配,调用宏 ret find_name endp ;---------------------------------------------------------------- ; 子程序:find_num | ; 功能:根据手机号查找 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- find_num proc ;根据手机号查找子程序 point 19,4 ;设置光标位置 highlight 4 ;高亮第四行 show num input num_buff ;输入号码到缓冲区 find 15,num_buff ;将缓冲区姓名与数据区进行匹配,调用宏 ret find_num endp ;---------------------------------------------------------------- ; 子程序:display | ; 功能:显示保存的所有数据 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- display proc near ;显示保存的所有数据 call cls ;清屏 point 0,0 ;设置光标位置 mov ah,0 mov al,sum ;ax保存联系人总数 cmp al,0 je empty ;al保存数据个数,空的时候显示空 mov cx,ax lea bx,storage ;数据区取偏移地址 outer: ;外层循环控制数据个数 push cx mov cx,30 inner: ;内层循环控制一个联系人的所有数据 mov dl,[bx] mov ah,6h int 21h ;调用中断显示数据 inc bx ;取下一个联系人数据 loop inner call newline ;每输出一个调用换行子程序 pop cx ;内层循环结束出栈cx保证外层循环正常进行 loop outer ret empty: show emp ret display endp ;---------------------------------------------------------------- ; 子程序:export | ; 功能:导出电话簿到文件 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- export proc near highlight 6 ;高亮第六行 mov cx,0 mov dx,offset filename ;ds:dx指定文件名字符串的地址 mov ah,3ch ;功能是创建文件 int 21h jc file_error ;创建失败cf=1退出 mov handle,ax ;句柄ax保存 mov bx,handle mov cx,offset name_buff-offset storage ;写入字节数 mov dx,offset storage ;ds:dx存放数据缓冲区地址 mov ah,40h ;功能向文件中写字节 int 21h jc file_error ;读入失败 mov bx,handle ;文件句柄 mov ah,3eh ;功能关闭文件 int 21h jc file_error ;关闭失败退出 call cls show fis ;文件操作失败 ret file_error: show fie call exit export endp ;---------------------------------------------------------------- ; 子程序:about | ; 功能:显示版权 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- about proc near call cls ;清屏 point 8,0 ;确定光标 show about_ ;显示 ret about endp ;---------------------------------------------------------------- ; 子程序:help | ; 功能:显示帮助 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- help proc near call cls ;清屏 point 0,0 ;确定光标 show help_ ;显示 ret help endp ;---------------------------------------------------------------- ; 子程序:cls | ; 功能:清屏并显示颜色 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- cls proc ;清屏子程序 mov ax,0600h ;向上滚行清窗口 mov bh,3ch ; mov cx,0000 ;窗口左上角 mov dx,184fh ;窗口右下角 int 10h ret cls endp ;---------------------------------------------------------------- ; 子程序:newline | ; 功能:换行 | ; 入口参数:无 | ; 出口参数:无 | ;---------------------------------------------------------------- newline proc ;换行子程序 mov ah,02h mov dl,0ah int 21h ret newline endp int9: ;新中断写入 push ax push bx push cx push es ;寄存器入栈 in al,60h ;读取扫描码到al pushf call dword ptr cs:[200h] ;调用旧中断例程 cmp al,3bh ;处理f1键,扫描码为3bh jne int9ret ;不是就退出 mov ax,0b800h mov es,ax ;改变显存内容 mov bx,1 mov cx,2000 ;改变整个每个页面及字体的颜色 s2: inc byte ptr es:[bx] add bx,2 loop s2 int9ret: pop es pop cx pop bx pop ax iret int9end:nop ;--------------------------------------------------------------- ; 子程序:be | ; 功能:开机界面 | ; 入口参数:无 | ; 出口参数:无 | ;--------------------------------------------------------------- be proc near ;开机界面过程 call time ;界面中显示时间 mov al,second+1 ;获取当前秒的个位 and al,0fh ;分离低位 add al,5 ;5s的开机界面 aaa ;加法调整 add al,30h ;数字转ascll mov time_p,al ;保存时间长度 mov dl,0 ;字符指针初始化 b_loop: inc dl ;每次显示时间,dl加一改变字符 push dx ;保存cpu现场 call cartoon ;显示动画 call time_delay ;时间流转 call cls ;清屏 call time ;再次查看此时的时间 mov al,second[1] .if time_p==al ;如果过了5s就结束返回 pop dx ;恢复cpu现场 ret ;返回主菜单 .endif point 7,0 ;设置界面语指向的坐标位置 show kmlj ;显示开幕动画 point 13,32 ;设置年分指向的坐标位置 show year ;几几年几几月几几日 point 14,33 ;设置时间指向的坐标位置 show hour ;几几时几几分几几秒 pop dx ;恢复cpu现场 jmp b_loop ;没到时间继续循环 ret ;返回主菜单 be endp ;--------------------------------------------------------------- ; 子程序:cartoon | ; 功能:动画边框 | ; 入口参数:dl | ; 出口参数:无 | ;--------------------------------------------------------------- cartoon proc near mov cl,1 ;字符指针初始化 mov ch,1 mov x1,23 ;左下角坐标位置 mov y1,78 ;右下角坐标位置 mov x2,1 ;右上角坐标位置 mov y2,1 ;左上角坐标位置 mov ah,2 ;使用21h号中断的显示输出功能 cartoon_loop1: point ch,cl ;两个指针指向的坐标位置 int 21h inc ch ;向下画一列 cmp ch,x1 ;判断长度是否超过左下角最大坐标 jnz cartoon_loop1 ;循环输出画图过程的全部字符 cartoon_loop2: point ch,cl int 21h inc cl ;向右画一行 cmp cl,y1 ;判断长度是否超过右下角最大坐标 jnz cartoon_loop2 ;循环输出画图过程的全部字符 cartoon_loop3: point ch,cl int 21h dec ch ;向上画一列 cmp ch,x2 ;判断长度是否超过右上角最大坐标 jnz cartoon_loop3 ;循环输出画图过程的全部字符 cartoon_loop4: point ch,cl int 21h dec cl ;向左画一行 cmp cl,y2 ;判断长度是否超过左上角最大坐标 jnz cartoon_loop4 ;循环输出画图过程的全部字符 ret ;返回主菜单 cartoon endp ;--------------------------------------------------------------- ; 子程序:time_delay | ; 功能:动态增加时间 | ; 入口参数:无 | ; 出口参数:无 | ;--------------------------------------------------------------- time_delay proc near ;时间延搁过程 push ax ;保存cpu现场 call time ;获取当前时间时间 mov al,second+1 ;获取当前秒的个位 and al,0fh ;分离出低位 add al,1 ;+1s aaa ;加法调整 add al,30h ;ascll转数字 ce_loop: call time ;界面中显示时间 cmp al,second+1 ;再和当前时间比较 jnz ce_loop ;循环输出时间延搁过程的全部字符 pop ax ;恢复cpu现场 ret ;返回主菜单 time_delay endp ;--------------------------------------------------------------- ; 子程序:time | ; 功能:获取系统年月日分钟秒并保存 | ; 入口参数:无 | ; 出口参数:无 | ;--------------------------------------------------------------- time proc near ;提取系统日期和时间过程 push ax ;保存cpu现场 push bx push cx push dx mov ah,2ah ;使用21h中断的读取日期功能 int 21h mov si,3 ;将字符指针右移3个单位,最低位开始 mov ax,cx ;把年放在ax寄存器中 mov cx,4 ;年是四个数,每次放一个数 year_loop: mov bl,0ah ;除以10 div bl ;分离每一位转ascll add ah,30h ;余数转ascll mov year[si],ah ;年的一位放到对应位置 mov ah,0 ;字符指针初始化 dec si ;字符指针左移 loop year_loop ;循环提取系统时间 htos dh,month ;提取系统月份 htos dl,day ;提取系统日期 mov ah,2ch ;使用21h中断的读取系统时间功能 int 21h htos ch,hour ;提取系统小时 htos cl,minute ;提取系统分钟 htos dh,second ;提取系统秒数 htos dl,s ;提取系统单位长度 pop dx ;恢复cpu现场 pop cx pop bx pop ax ret ;返回主菜单 time endp ;--------------------------------------------------------------- ; 子程序:gensound | ; 功能:发声 | ; 入口参数:无 | ; 出口参数:无 | ;--------------------------------------------------------------- gensound proc near push ax push bx push cx push dx push di mov al, 0b6H ;8253初始化 out 43h, al ;43h是8253芯片控制口的端口地址 mov dx, 12h mov ax, 348ch div di ;计算分频值 out 42h, al ;先送低8位到计数器,42h是8253芯片通道2的端口地址 mov al, ah out 42h, al ;后送高8位计数器 in al, 61h ;读取8255 B端口原值 mov ah, al ;保存原值 or al, 3 ;使低两位置1,以便打开开关 out 61h, al ;开扬声器,发声 wait1: mov cx, 3314 ;延时,保持时间 call waitf delay1: dec bx jnz wait1 mov al, ah out 61h, al ;恢复扬声器端口原值 pop di pop dx pop cx pop bx pop ax ret ;恢复寄存器返回 gensound endp ;--------------------------------------------------------------- ; 子程序:waitf | ; 功能:发声延迟 | ; 入口参数:cx | ; 出口参数:无 | ;--------------------------------------------------------------- waitf proc near ;和cpu无关的延时程序:产生n*15.08微秒延时 push ax waitf1: in al,61h and al,10h cmp al,ah ;判断61h的PB4=1否? je waitf1 ;(15.08微秒延时到PB4=1) mov ah,al loop waitf1 ;产生50ms延时,cx=50*10^3/15.08μs=3314 pop ax ret waitf endp ;--------------------------------------------------------------- ; 子程序:music | ; 功能:发声主程序 | ; 入口参数:无 | ; 出口参数:无 | ;--------------------------------------------------------------- music proc near xor ax, ax freg: mov di, [si] cmp di, -1 ;取音频 je end_mus ;结束 mov bx, ds:[bp] call gensound ;演奏一个音符 add si, 2 add bp, 2 ;下一个音符 jmp freg end_mus: ret music endp end main ;结束,allover
我喜欢能带给我正面影响的人,正面影响不代表对方有多棒,但我希望对方可以肯定我,看得到我身上发光的地方 。