课程设计--简易电话簿

来源:互联网 发布:捷通华声语音合成软件 编辑:程序博客网 时间:2024/05/21 02:35
  1. 题目要求
    本题目是完成一个较为简单的电话本程序,能够实现插入信息(包括姓名和号码),查询信息(分为通过姓名查询和通过号码查询),显示所有联系人信息,数据导出到文本文件,修改背景颜色,字体颜色
  2. 题目分析
    (1) 显示菜单与功能选择
    可以使用代码的直接定址表,根据输入的序号得到对应的直接定址表中标号的地址,调用相应子程序,实现功能
    (2) 数据存储方式
    为了方便存储与查找,设定固定长度的内存空间存储姓名和号码,将人名和电话号码各以15个字节为单位存入数据单元中,不够补空格,并且是号码紧挨着人名排,以便查找。
    因为使用21号中断的10号功能来输入字符串,所以分别设定姓名缓冲区,号码缓冲区,暂存用户输入的字符串。
    内存中有一位用来存储当前用户个数,方便查找和显示所有信息。
    将多条提示语句预先存在数据区,方便根据标号进行调用。
    (3) 数据查找方式
    通过姓名查询时,将用户输入到缓冲区的姓名与存储姓名的数据段的多条内容逐位比较,若能顺利读到该条数据的最后一位,即表示字符串匹配成功,即查找成功,通过号码查找同理。
    (4) 文件操作
    调用21号中断的3ch号功能,将数据段中的信息导出到文本文档。
    (5) 字体,背景颜色操作
    通过修改显存,改变字体和背景颜色。由于只能操作当前页的颜色,可以选择每次跳出菜单之前进行清屏,保证所有操作都在当前页进行。
    F1键改变颜色,通过改写中断,定制键盘实现
    (6) 显示提示信息
    通过21号中断的9号功能显示数据段中的提示信息。由于很多地方都用到了,可以将该功能写成宏,把标号当做参数进行调用
    (7) 多文件组织
    由于代码较长,可以使用多文件进行组织
  3. 源代码
.8086.MODEL small.data      dw 0,0table 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 21hendm    main procstart:     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_screendisp:      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 21hQuit  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    retAddPerson 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,axfind1:    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 dispok1:     call clear_screen    pop di    mov cx,30print1:    mov dl,[di]   ;要输出的字符的ASCII码    mov ah,06h    ;21号中断的6号功能    int 21h    inc di    loop print1    call wrap         ;换行    pop cx      jmp dispSearchByName 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,axfind2:    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 dispok2:     call clear_screen    pop di    sub di,15    mov cx,30print2:    mov dl,[di]        ;要输出的字符的ASCII码    mov ah,06h        ;21号中断的6号功能    int 21h    inc di    loop print2    call wrap             ;换行    pop cx      jmp dispSearchByNum 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    retinput_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    retinput_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,30print:    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     retDisplayAll  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     retExportTxt  endp;*****************************************************************; 子程序:wrap; 功能:输出换行; 入口参数:无; 出口参数:无;*****************************************************************wrap proc    mov dl,0Dh    mov ah,2    int 21h    mov dl,0Ah    mov ah,2    int 21h    retwrap endp;*****************************************************************; 子程序:clear_screen; 功能:清屏; 入口参数:无; 出口参数:无;调用注意事项:会改变es的值,要注意对其进行保护,可通过调整调用的位置或者设置寄存器压栈;*****************************************************************clear_screen proc    mov ax,0b800h    mov es,ax    mov bx,0    mov cx,2000p:     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号功能,设置光标位置    retclear_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,2000r:     inc byte ptr es:[bx]   ;每一位字符颜色属性值加一    add bx,2    loop rint9ret:    pop es    pop cx    pop bx    pop ax    iretint9end:nopmain endp      end start
原创粉丝点击