课程设计--简易电话簿

xiaoxiao2021-02-28  111

题目要求 本题目是完成一个较为简单的电话本程序,能够实现插入信息(包括姓名和号码),查询信息(分为通过姓名查询和通过号码查询),显示所有联系人信息,数据导出到文本文件,修改背景颜色,字体颜色题目分析 (1) 显示菜单与功能选择 可以使用代码的直接定址表,根据输入的序号得到对应的直接定址表中标号的地址,调用相应子程序,实现功能 (2) 数据存储方式 为了方便存储与查找,设定固定长度的内存空间存储姓名和号码,将人名和电话号码各以15个字节为单位存入数据单元中,不够补空格,并且是号码紧挨着人名排,以便查找。 因为使用21号中断的10号功能来输入字符串,所以分别设定姓名缓冲区,号码缓冲区,暂存用户输入的字符串。 内存中有一位用来存储当前用户个数,方便查找和显示所有信息。 将多条提示语句预先存在数据区,方便根据标号进行调用。 (3) 数据查找方式 通过姓名查询时,将用户输入到缓冲区的姓名与存储姓名的数据段的多条内容逐位比较,若能顺利读到该条数据的最后一位,即表示字符串匹配成功,即查找成功,通过号码查找同理。 (4) 文件操作 调用21号中断的3ch号功能,将数据段中的信息导出到文本文档。 (5) 字体,背景颜色操作 通过修改显存,改变字体和背景颜色。由于只能操作当前页的颜色,可以选择每次跳出菜单之前进行清屏,保证所有操作都在当前页进行。 F1键改变颜色,通过改写中断,定制键盘实现 (6) 显示提示信息 通过21号中断的9号功能显示数据段中的提示信息。由于很多地方都用到了,可以将该功能写成宏,把标号当做参数进行调用 (7) 多文件组织 由于代码较长,可以使用多文件进行组织源代码 .8086 .MODEL small .data dw 0,0 table dw Quit,AddPerson,SearchByName,SearchByNum,DisplayAll,ExportTxt ;代码的直接定址表,存放各功能代码块的偏移地址 menu db 10,13,10,13,' MENU ' db 10,13 db 10,13,'1. Add Person' db 10,13,'2. Search By Name' db 10,13,'3. Search By Num' db 10,13,'4. Display All' db 10,13,'5. ExportTxt' db 10,13,'0. Quit' db 10,13 db 10,13,'please choose one of 0~5:','$' content db 20 dup(15 dup (0),15 dup (0)) ;存储姓名,号码 name_buff db 15, ?, 15 DUP(?) ;输入缓冲区,21号中断10号功能 num_buff db 15, ?, 15 DUP(?) count db 0 ;记录存储的信息条数 filename db 'data.txt',0 ;导出文件的文件名 handle dw ? ;导出文件的文件句柄 add1 db 10,13,'please input the name:','$' add2 db 10,13,'please input the num:','$' succ db 10,13,'Operation is successful!','$' fail db 10,13,'No data at the moment!','$' no_find db 10,13,'The message does not exist!','$' .stack 128 .code ;***************************************************************** ; 宏指令:subprog ; 功能:显示指定标号处的字符串 ; 入口参数:_Label——表示字符串标号 ; 出口参数:无 ;***************************************************************** show macro _Label lea dx,_Label ;字符串标号 mov ah,9 int 21h endm main proc start: push cs pop ds mov ax,0 mov es,ax lea si,int9 mov di,204h ;安装新程序 mov cx,offset int9end - offset int9 cld rep movsb ;保存原中断例程入口地址 push es:[9*4] pop es:[200h] push es:[9*4+2] pop es:[202h] cli ;改变后中断的入口地址 mov word ptr es:[9*4],204h ;IP mov word ptr es:[9*4+2],0 ;CS sti mov ax,@data mov ds,ax call clear_screen disp: show menu mov ah,1 int 21h ;调用21h中断的第1号功能,从键盘读入字符,AL保存读入字符的ASCII码 cmp al,30h jb no cmp al,35h ja no sub al,30h ;将输入的ASCII码转为BCD码 mov bl,al mov bh,0 add bx,bx ;数字乘2才是直接定址表中的标号的地址 call word ptr table[bx] ;调用子程序 jmp disp ;重复显示菜单 no:call clear_screen jmp disp ;***************************************************************** ; 子程序:Quit ; 功能:退出程序 ; 入口参数:无 ; 出口参数:无 ;***************************************************************** Quit proc near mov ah,4ch int 21h Quit endp ;***************************************************************** ; 子程序:AddPerson ; 功能:向内存中添加一条信息 ; 入口参数:无 ; 出口参数:无 ;***************************************************************** AddPerson proc show add1 call input_name ;输入姓名到缓冲区 ;从缓冲区传到存放数据的地址 lea di,content mov ax,@data mov es,ax mov ah,0 mov al,count mov bl,30 mul bl add di,ax ;当前存储条数*30,得到新姓名起始地址 lea si,name_buff+2 ;从第三个字节开始存储数据 cld mov cx,15 rep movsb ;串传送 show add2 call input_num ;输入号码到缓冲区 ;从缓冲区传到存放数据的地址 lea di,content mov ax,@data mov es,ax mov ah,0 mov al,count mov bl,30 mul bl add di,ax add di,15 ;当前存储条数*30+15,得到新号码起始地址 lea si,num_buff+2 ;从第三个字节开始存储数据 cld mov cx,15 rep movsb ;串传送 call clear_screen show succ ;数据区存放的人数加一 add byte ptr count,1 ret AddPerson endp ;***************************************************************** ; 子程序:SearchByName ; 功能:通过姓名查找对应信息,并显示在屏幕上 ; 入口参数:无 ; 出口参数:无 ;***************************************************************** SearchByName proc show add1 call input_name ;输入姓名到缓冲区 lea di,content push di mov bl,count mov bh,0 ;bx存储当前剩余的要比较的数据条数 mov ax,@data mov es,ax find1: lea si,name_buff+2 mov cx,15 repe cmpsb ;比较 si 和bi的前15个字节 jz ok1 ;不相等时不跳转 pop di add di,30 ;di 偏移地址加20 push di dec bx jnz find1 ;bx不为0则继续比较下一条信息 call clear_screen show no_find jmp disp ok1: call clear_screen pop di mov cx,30 print1: mov dl,[di] ;要输出的字符的ASCII码 mov ah,06h ;21号中断的6号功能 int 21h inc di loop print1 call wrap ;换行 pop cx jmp disp SearchByName endp ;***************************************************************** ; 子程序:SearchByNum ; 功能:通过号码查找对应信息,并显示在屏幕上 ; 入口参数:无 ; 出口参数:无 ;***************************************************************** SearchByNum proc show add2 call input_num ;输入号码到缓冲区 lea di,content+15 push di mov bl,count ;bx存储当前剩余的要比较的数据条数 mov bh,0 mov ax,@data mov es,ax find2: lea si,num_buff+2 mov cx,15 repe cmpsb ;比较 si 和di的前15个字节 jz ok2 ;不相等时不跳转 pop di add di,30 ;di 偏移地址加30 push di dec bx jnz find2 ;bx不为0则继续比较下一条信息 call clear_screen show no_find jmp disp ok2: call clear_screen pop di sub di,15 mov cx,30 print2: mov dl,[di] ;要输出的字符的ASCII码 mov ah,06h ;21号中断的6号功能 int 21h inc di loop print2 call wrap ;换行 pop cx jmp disp SearchByNum endp ;***************************************************************** ; 子程序:input_name ; 功能:输入姓名到缓冲区 ; 入口参数:name_buff---表示姓名缓冲区的起始地址 ; 出口参数:无 ;***************************************************************** input_name proc lea dx,name_buff mov ah,10 int 21h ;21号中断的10号功能,输入字符串到缓冲区,回车结束输入 mov bh,0 mov bl,name_buff+1 ;bl 存放从键盘输入的字符串长度 mov cx,15 sub cx,bx ;计算剩下的长度 comp1: mov name_buff[bx+2],20h ;剩下的地方补空格 inc bx loop comp1 ret input_name endp ;***************************************************************** ; 子程序:input_num ; 功能:输入号码到缓冲区 ; 入口参数:num_buff---表示号码缓冲区的起始地址 ; 出口参数:无 ;***************************************************************** input_num proc lea dx,num_buff mov ah,10 int 21h ;21号中断的10号功能,输入字符串到缓冲区,回车结束输入 mov bh,0 mov bl,num_buff+1 ;用bl 存放从键盘输入的字符串长度 mov cx,15 sub cx,bx ;计算剩下的长度 comp2: mov num_buff[bx+2],20h ;剩下的地方补空格 inc bx loop comp2 ret input_num endp ;***************************************************************** ; 子程序:DisplayAll ; 功能:将数据区所有的用户和号码打印到屏幕 ; 入口参数:count——表示数据区所有的信息条数 ; content——表示信息的起始地址 ; 出口参数:无 ;***************************************************************** DisplayAll proc near call clear_screen mov al,count cmp al,0 jz return mov ah,0 mov cx,ax lea bx,content ;数据的起始地址 s: push cx mov cx,30 print: mov dl,[bx] ;要打印的字符ASCII码 mov ah,06h ;21号中断的6号功能 int 21h inc bx loop print call wrap pop cx loop s ret ;显示提示字符串 return: show fail ret DisplayAll endp ;***************************************************************** ; 子程序:ExportTxt ; 功能:将数据区中的所有姓名和号码导出到文本文件 ; 入口参数:filename——表示文件名 ; 出口参数:cx——在cx中存放…… ; [bx]——在bx指示的单元中…… ;调用注意事项:由于要利用cx返回处理结果,注意在调用程序中保护cx的值 ;***************************************************************** ExportTxt proc near ;创建文件 lea dx,filename mov cx,0 mov ah,3ch int 21h ;21号中断的3c号功能,用指定的文件名创建一个新文件 mov handle,ax ;保存文件句柄 ;向文件中写入文本 mov bx,handle mov cx,offset name_buff-offset content lea dx,content ;dx存储起始地址 mov ah,40h ;21号中断的40号功能 int 21h ;关闭文件 mov bx,handle mov ah,3eh int 21h ;显示提示字符串 call clear_screen show succ ret ExportTxt endp ;***************************************************************** ; 子程序:wrap ; 功能:输出换行 ; 入口参数:无 ; 出口参数:无 ;***************************************************************** wrap proc mov dl,0Dh mov ah,2 int 21h mov dl,0Ah mov ah,2 int 21h ret wrap endp ;***************************************************************** ; 子程序:clear_screen ; 功能:清屏 ; 入口参数:无 ; 出口参数:无 ;调用注意事项:会改变es的值,要注意对其进行保护,可通过调整调用的位置或者设置寄存器压栈 ;***************************************************************** clear_screen proc mov ax,0b800h mov es,ax mov bx,0 mov cx,2000 p: mov byte ptr es:[bx],' ' ;将该页字符全部置为空格,实现清屏 add bx,2 loop p mov ah,02h mov bh,0 ; 显示页码 mov dx,0 ; x轴 y轴均置为0 int 10h ;10号中断的2号功能,设置光标位置 ret clear_screen endp ;***************************************************************** ; 子程序:int9 ; 功能:改写int9中断。定制键盘输入 ;调用注意事项:由于要利用cx返回处理结果,注意在调用程序中保护cx的值 ;***************************************************************** int9: push ax push bx push cx push es in al,60h ;读取键盘扫描码 pushf ;标志寄存器入栈 call dword ptr cs:[200h] ;调用旧中断例程,处理硬件细节 cmp al,3bh ;等于F1键的扫描码 jne int9ret mov ax,0b800h mov es,ax ;操作显存 mov bx,1 mov cx,2000 r: inc byte ptr es:[bx] ;每一位字符颜色属性值加一 add bx,2 loop r int9ret: pop es pop cx pop bx pop ax iret int9end:nop main endp end start
转载请注明原文地址: https://www.6miu.com/read-44595.html

最新回复(0)