汇编语言电话本管理课程设计使用masm forwindows 运行.docx
《汇编语言电话本管理课程设计使用masm forwindows 运行.docx》由会员分享,可在线阅读,更多相关《汇编语言电话本管理课程设计使用masm forwindows 运行.docx(37页珍藏版)》请在冰豆网上搜索。
汇编语言电话本管理课程设计使用masmforwindows运行
一、软件背景介绍
汇编语言是一种以处理器指令系统为基础的低级程序设计语言,采用助记符表达指令操作码,采用标识符表示指令操作数。
它是一种面向机器,效率最高的程序设计语言。
它具有很高的系统资源操作能力和较高的程序执行效率,非常适合与系统程序的设计。
汇编语言可以开发出许多应用软件,利用汇编语言编写的程序的主要优点是可以直接、有效地控制计算机硬件,因而容易创建代码序列减小、运行快速的可执行程序,在某些应用领域汇编语言的作用是不容置疑和不可替代的。
现在,通讯越来越发达,通讯录的存在成为必需。
所以,应要求设计一个电话本,其功能如下:
1.程序能够建立一个可存放30条以上记录的电话号码本;
2.程序能够对记录进行查找、增加、删除、修改操作;
3.录入字段包含姓名、电话、单位内容;
4.通过姓名或电话查询记录并显示查询结果。
程序运行后,显示一操作菜单,含录入、列示、查询和退出功能,用单字母进行功能选择。
m–修改;d–删除;n–插入;v–浏览;f-查询;e–退出,返回DOS。
录入操作能从键盘录入姓名、电话号码、工作单位的通讯录(不超过30人)存于内存数据区。
列示功能能列出所有录入的资料。
查询功能能按姓名查询通讯录,列出查找到的记录或给出未找到信息。
图1程序运行后的界面图
图1中界面的实现是由图2的总流程图实现的。
进入程序后,显示功能菜单:
f-查询;n–插入;m–修改;d–删除;v–浏览;e–退出,返回DOS。
图2总体程序流程图
二、核心算法思想
电话本系统程序应用字符串操作命令,实现了个人通讯信息的增加、删除、修改、查询。
信息连续存储,设有计数器cnt总是保存最后一条记录的序号。
插入时自动插入到最后一条记录后,同时cnt加1。
删除时,用最后一条记录覆盖被删除的记录,cnt减1。
每个字段均有自己的输入缓冲区和记录存储区。
程序执行后,首先显示功能选择界面,根据提示,输入要完成功能的代号,进入相应的子程序。
查询:
显示选择菜单:
1–按姓名查找;2–按电话查找。
按姓名查找:
输入查找内容到缓冲区,将其与记录姓名进行比较,相等输出,返回主程序。
否则进行下一目录比较;按电话查找:
输入查找电话到缓冲区,将其与记录电话进行比较,相等输出,返回主程序。
否则进行下一目录比较。
插入:
检测cnt是否为30:
是,电话本已满,拒绝插入,返回主程序;否,输入新的内容,将其插入到cnt后的存储单元中,cnt加1,清空缓存,以便用于下一次输入。
提示添加成功。
修改:
调用slebyname,检测cntselect是否为0:
是,没有查到,返回;否,输入新内容到缓冲区,计算被修改内容的偏移量,送新内容,cntselect清零。
删除:
检测cnt是否为0:
是,电话本为空,返回主菜单;否,调用slebyname,检测cntselect是否为0:
是,没有查到,返回;否,计算要删除数据的偏移量,用最后一条记录覆盖要删除的记录,cnt减1。
显示:
检测cnt是否为0:
是,电话本为空,返回主菜单;否,显示第一条记录、姓名、电话、办公室。
输入n–若没有显示完毕,显示下一跳,否则返回;p–若本记录为第一条,返回,否则输出前一条;e–退出。
退出:
返回DOS。
信息录入:
对于查询、删除、修改、以及插入,均需录入新内容以便进行字符匹配与增加,所以我们调用DOS功能中的0A号功能与01号功能,进行字符串与字符的输入。
执行AH=01H号功能调用,从键盘读取一个字符,将该字符回显到屏幕上。
主要用与菜单功能选择和对不定长字符串的录入。
当输入回车时,加入“$”为字符串传送做准备。
执行AH=0AH号功能调用,等待用户输入一个或多个字符,最后用回车确认。
信息输出:
当查到用户所需内容时,或用户输入数据超范围或成功输入时,都需要显示信息或提示。
我们采用DOS功能调用中的09号与ROM-BIOS功能调用中的13号功能。
执行AH=09H号功能调用,从当前光标开始显示DS:
DX指向的以“$”为结尾的字符串。
该调用也可以输出回车和换行字符产生回车和换行的作用。
信息处理:
当输入新内容后,若要完成查询、插入、删除、修改功能,还要调用字符串处理命令。
传送利用MOVSB命令,比较应用CMPSB命令。
MOVSB命令将数据段中的一个字节传送至附加段的主存单元。
CMPSB命令用源数据串减去目的数据串,以比较两者之间的关系,配合REPE或REPNE使用。
屏幕设置:
INT10H是由BIOS对屏幕及显示器所提供的服务程序,可设置一个人性化的窗口。
我们调用ROM-BIOS功能,使用6号功能使屏幕初始化或上卷,使用2号功能设定光标位置。
三、核心算法流程图
1、查询:
显示选择菜单:
1–按姓名查找;2–按电话查找。
若输入的是1就调用按姓名查找函数。
若输入的是2则调用按电话查找函数
图3查询功能模块流程图
2、插入:
检测cnt是否为30:
是,电话本已满,拒绝插入,返回主程序;否,输入新的内容,将其插入存储单元中,清空缓存,以便用于下一次输入。
提示添加成功。
图4插入子程序流程
3、修改:
调用slebyname,检测cntselect是否为0:
是,没有查到,返回;否,输入新内容到缓冲区,计算被修改内容的偏移量,送新内容,cntselect清零。
图5修改子程序流程图
4、删除:
检测cnt是否为0:
是,电话本为空,返回主菜单;否,调用slebyname,检测cntselect是否为0:
是,没有查到,返回;否,计算要删除数据的偏移量,用最后一条记录覆盖要删除的记录,cnt减1。
N
Y
Y
N
图6删除子程序流程图
四、源代码
winmacroopr1,opr2,opr3,opr4,opr5,opr6;建立窗口
pusha
movah,06h
moval,opr1
movbh,opr2
movch,opr3
movcl,opr4
movdh,opr5
movdl,opr6
int10h
popa;恢复原来寄存器数据
endm
pos_cursemacroop1,op2,op3;定义光标位置
pusha;储存原来寄存器数据
movah,2
movbh,op1
movdh,op2
movdl,op3
int10h
popa;恢复原来寄存器数据
endm
printfmacrox,y,string;建立输出程序
pusha
movax,segstring;将string所在段的段地址传给ax
moves,ax
movah,13h
moval,2
movbh,0
movcx,(SIZEOFstring)/2
movdh,x
movdl,y
movbp,OFFSETstring;将string所在的偏移地址传参给bp
int10h
popa
endm
printf2macrox,y,string
pusha
pos_curse0,x,y
movah,9h
movdx,OFFSETstring;将string所在的偏移地址传参给dx
int21h
popa
endm
stacksegmentstack;建立栈
dw512dup(?
)
stackends
datasegment
viewstrdb'',0e1h,'V',0e1h,'i',0e1h,'e',0e1h,'w',0e1h,'(',0e1h,'V',0e1h,')',0e1h,'',0e1h;菜单view
findstrdb'',0e1h,'F',0e1h,'i',0e1h,'n',0e1h,'d',0e1h,'(',0e1h,'F',0e1h,')',0e1h,'',0e1h
exitstrdb'',0e1h,'E',0e1h,'x',0e1h,'i',0e1h,'t',0e1h,'(',0e1h,'E',0e1h,')',0e1h,'',0e1h
modifystrdb'',0e1h,'M',0e1h,'o',0e1h,'d',0e1h,'i',0e1h,'f',0e1h,'y',0e1h,'(',0e1h,'M',0e1h,')',0e1h,'',0e1h
deletestrdb'',0e1h,'D',0e1h,'e',0e1h,'l',0e1h,'e',0e1h,'t',0e1h,'e',0e1h,'(',0e1h,'D',0e1h,')',0e1h,'',0e1h
newstrdb'',0e1h,'N',0e1h,'e',0e1h,'w',0e1h,'(',0e1h,'N',0e1h,')',0e1h,'',0e1h
nextstrdb'',0e1h,'N',0e1h,'e',0e1h,'x',0e1h,'t',0e1h,'(',0e1h,'N',0e1h,')',0e1h,'',0e1h
prestrdb'',0e1h,'P',0e1h,'r',0e1h,'e',0e1h,'v',0e1h,'(',0e1h,'P',0e1h,')',0e1h,'',0e1h
titlestrdb'Welcometotelephonedirectory!
',0dh,0ah,'Enteryourchoiceplease!
',0dh,0ah,'$'
menustrdb'1:
Select',0dh,0ah,'2:
Insert',0dh,0ah,'3:
Modify',0dh,0ah,'4:
Delete',0dh,0ah,'5:
Showallrecord',0dh,0ah,'8:
Esc',0dh,0ah,'$'
enter1db0dh,0ah,'$'
numdb'No.1$',15dup(0),'No.2$',15dup(0),'No.3$',15dup(0),'No.4$',15dup(0),'No.5$',15dup(0)
db'No.6$',15dup(0),'No.7$',15dup(0),'No.8$',15dup(0),'No.9$',15dup(0),'No.10$',14dup(0)
db'No.11$',14dup(0),'No.12$',14dup(0),'No.13$',14dup(0),'No.14$',14dup(0),'No.15$',14dup(0)
db'No.16$',14dup(0),'No.17$',14dup(0),'No.18$',14dup(0),'No.19$',14dup(0),'No.20$',14dup(0)
db'No.21$',14dup(0),'No.22$',14dup(0),'No.23$',14dup(0),'No.24$',14dup(0),'No.25$',14dup(0)
db'No.26$',14dup(0),'No.27$',14dup(0),'No.28$',14dup(0),'No.29$',14dup(0),'No.30$',14dup(0)
db'No.31$',14dup(0),'No.32$',14dup(0),'No.33$',14dup(0),'No.34$',14dup(0),'No.35$',14dup(0)
db'No.36$',14dup(0),'No.37$',14dup(0),'No.38$',14dup(0),'No.39$',14dup(0),'No.40$',14dup(0)
namelistdb40dup(20dup(0));存储40个姓名
telelistdb40dup(20dup(0));存储40个电话
unitlistdb40dup(20dup(0));存储40个单位名称
newnamedb20dup(0);插入用
newteledb20dup(0);插入用
newunitdb20dup(0)
cntdb1dup(0)
cntselectdb1dup(0)
choicedb1dup(0)
disnamedb'Name:
$';将字符串“name:
”放到disname中
disteledb'Tele:
$';将字符串“tele:
”放到distele中
disunitdb'Unit:
$';将字符串“unit:
”放到disunit中
backstrdb'Pressanykeytomainmenu!
',0dh,0ah,'$'
disstrdb'Allrecord!
',0dh,0ah,'$'
selstr10db'Choosethewaytoselect:
$'
selstr11db'1:
Selectbyname$'
selstr12db'2:
Selectbytelephone',0dh,0ah,'$'
selstr2db'Theimformation!
',0dh,0ah,'$'
selstr3db'Nameisnotexist!
',0dh,0ah,'$'
selstr4db'Telephoneisnotexist!
',0dh,0ah,'$'
selstr5db'Telephonedirectoryisempty!
',0dh,0ah,'$'
addstr1db'Inputthenewnameandthenewtelephonenumber!
',0dh,0ah,'$'
addstr2db'Telephonedirectoryisfull!
',0dh,0ah,'$'
addstr3db'Addsuccessfully!
',0dh,0ah,'$'
massdb'$'
modstr1db'Name:
$'
modstr2db'Phone:
$'
modstr3db'Inputnewrecord:
',0dh,0ah,'$'
modstr4db'Modifiedsuccessfully!
',0dh,0ah,'$'
delstr1db'Telephonedirectoryisempty!
',0d,0ah,'$'
delstr2db'Deletedsuccessfully!
',0dh,0ah,'$'
disstr11db'Norecord!
$'
dataends
codesegment
mainprocfar
assumecs:
code,ds:
data;将代码段放入cs,将数据段放入ds
movax,data
movds,ax
moves,ax
menu1:
calldisplaytitle;调用窗口排布函数
movah,01h
int21h
cmpal,'f';将输入的al里的字母和f比较看是否相同
jzsel;与f相同则跳到sel指示的子程序去
cmpal,'n';将输入的al里的字母和n比较看是否相同
jzadde;与N相同则跳到adde指示的子程序去
cmpal,'m';将输入的al里的字母和m比较看是否相同
jzmodi;与M相同则跳到modi指示的子程序去
cmpal,'d';将输入的al里的字母和d比较看是否相同
jzdel;与D相同则跳到del指示的子程序去
cmpal,'v';将输入的al里的字母和V比较看是否相同
jzdis;与V相同则跳到dis指示的子程序去
cmpal,'e';将输入的al里的字母和E比较看是否相同
jzout1;与e相同
jmpmenu1
sel:
callselect;sel指示查询程序
jmpback;跳回
adde:
calladder;adde指示增加程序
jmpback;跳回
modi:
callmodify;modi指示修改程序
jmpback;跳回
del:
calldelete;del指示删除程序
jmpback;跳回
dis:
calldisdata;dis指示罗列所有基本信息
back:
movah,01h
int21h
jmpmenu1;输入e,返回主菜单
jmpback;美化函数
displaytitleprocnear
win0,9eh,0,0,24d,79d;定义窗口背景
printf6,68,viewstr;定义背景窗口的查询
printf9,68,findstr;定义背景窗口的查询
printf12,68,exitstr;定义背景窗口的退出
printf20,5,modifystr;定义背景窗口的修改
printf20,20,deletestr;定义背景窗口的删除
printf20,35,newstr;定义背景窗口的新建
pos_curse0,9,30
ret
displaytitleendp;窗口定义介绍
disdataprocnear;浏览子程序
win0,9eh,0,0,24d,79d;浏览子程序的背景
printf6,68,nextstr;输出next(n)
printf10,68,prestr;输出pres(p)
printf14,68,exitstr;输出exit(e)
leasi,cnt
movcl,[si];cl=cnt,从第一条开始输出,共输出cl条
movbx,0;bx置0
cmpcl,0;cl置0
jzdisdata2;跳到输出数据2
disdata1:
win0,9eh,2,0,19d,67d;浏览子程序
pos_curse0,5,10
leadx,num;找到电话排在第几位
adddx,bx;将bx中的数据与dx相加
movah,09h
int21h;sxn
printf27,10h,disname
leadx,namelist;找到姓名列表
adddx,bx;将bx中的数据与dx相加
movah,09h
int21h;sxn
printf29,10h,distele
leadx,telelist;找到电话列表
adddx,bx;将bx中的数据与dx相加
movah,09h;123
int21h
printf211,10h,disunit;找到所在的
leadx,unitlist
adddx,bx;将bx中的数据与dx相加
movah,09h
int21h;sxn
disdata6:
movah,01h
int21h
cmpal,'n';next
jnzdisdata4
addbx,20;下条记录
moval,cnt
movcl,20
mulcl
cmpbx,ax
jldisdata5
movbx,0
jmpdisdata1;跳到下条指令
disdata4:
cmpal,'p';检验AL寄存器内的值是不是p
jnzdisdata3
subbx,20
cmpbx,0
jnldisdata5
movbx,0
disdata5:
jmpdisdata1
disdata2:
printf29h,14,disstr11
ret
disdata3:
cmpal,'e';检验AL寄存器内的值是不是e
jnzdisdata6
ret
disdataendp
adderprocnear
win0,9eh,2,0,19d,67d
leasi,cnt;判断电话簿是否已满,超过40不再插入
moval,[si]
cmpal,40;检验AL寄存器内的值是不是40
jbadder5
leadx,addstr2;显示addstr2中的字符串
movah,09h
int21h
jmpadder6
adder5:
printf205h,10h,addstr1
printf207h,10h,disname
movcl,19
leasi,newname;将newname的偏移地址放到si中,使si指向newname
adder1:
movah,01h
int21h
cmpal,0dh
jeadder2
mov[si],al
incsi
loopadder1
adder2:
moval,24h
mov[si],al
leasi,cnt;计算目的地址的偏移量
movbl,[si]
xorax,ax
moval,20
mulbl
leasi,newname;将newname的偏移地址放到si中,使si指向newname
leadi,namelist;将namelist的偏移地址放到的di中,使di指向namelist
adddi,ax
movcx,20
cld
repmovsb;将新输入的名字插入namelist
leadx,enter1
movah,09h;实现DOS调用中的09号功能
int21h
printf29h,10h,distele
movcl,19
leasi,newtele
adder3:
movah,01h;实现DOS调用中的01号功能
int21h
cmpal,0dh;检验AL寄存器内的值是不是0x0D
jeadder4
mov[si],al
incsi;将si的内容自增
loopadder3
adder4:
moval,24h
mov[si],al
leasi,cnt