基于汇编语言学生成绩管理系统.docx
《基于汇编语言学生成绩管理系统.docx》由会员分享,可在线阅读,更多相关《基于汇编语言学生成绩管理系统.docx(35页珍藏版)》请在冰豆网上搜索。
基于汇编语言学生成绩管理系统
学生成绩管理系统
设计内容2
设计目的2
设计要求2
设计分析2
子程序分析7
操作说明10
程序代码11
总结30
参考文献30
设计内容
设计一个学生成绩管理程序,要求能实现以下功能:
1)各科成绩的录入,修改和删除。
2)按姓名查询每个学生各门课的成绩。
3)显示查询结果。
4)统计个分数段的人数。
5)打印学生成绩。
设计目的
用汇编数据的录入、修改和删除操作。
设计要求
学习如何用汇编语言进行数据处理。
设计分析
1.总体结构
整个程序采用主程序调用子程序的方法。
主程序完成菜单的显示,子程序完成一个独立功能方法的实现。
各子程序的实现方法简要描述如下:
1)设计INSERT(录入)子程序,先打开文件SCORE.TXT,并置文件指针到文件尾,然后调用GET_REC子程序接受用户的输入,再把用户的输入写入文件,最后关闭文件返回主程序。
2)设计Delete(删除)子程序,先打开文件,再调用宏GETIN得到要删除的学生的姓名,然后读文件中的记录,直到其记录的名字与所输入的名字相同为止,把文件指针后退8个字符(即4门课成绩所占的空间),写入8个“0”字符,关闭文件返回主程序。
3)设计List(浏览)子程序时,先打开文件,然后读一个记录,并通过调用宏SHOW_ITEM将其显示到屏幕上,入文件指针没有到达文件尾,则继续读记录并显示,当指针到达文件尾时,则关闭文件返回主程序。
4)设计Modify(修改)子程序时,先打开文件SCORE.TXT,通用GER_REC得到要修改的记录,然后读文件中的记录,并与用户输入的记录做比较(只比较记录中的名字部分),若不同则吨下一条记录,若相同则将文件指针后退23个字符(一个记录为23个字符的长度),然后把用户输入的记录写入文件,最后关闭文件返回主程序。
5)设计Count(统计)子程序时,先打开文件,然后读记录,比较记录的第16个字符,数学成绩的高位),并统计,直到文件指针到达文件尾,最后关闭文件调用宏SHOW_ITEM显示统计结果,返会主程序。
6)设计Query(查询)子程序时,先打开文件,通过调用宏GETIN得到要查找学生的姓名,然后读文件记录,并同要查找的学生姓名比较,若相同则输出,若不同继续读文件记录,最后显示查询结果,关闭文件返回程序。
另外还有打印的分数段人数统计,这些结合后面的子程序功能分析做详细介绍。
图1是本设计显示记录的界面
图1学生成绩管理系统界面
程序流程图如图2所示
Y
N
Y
N
A)List流程图B)Insert流程图
YY
NN
N
Y
NY
Y
N
Y
N
Y
N
Y
N
Y
N
Y
N
N
Y
在大型的程序中,为了使程序清晰、可读性好,一般会大量使用宏和子程序,因此,充分了解这些宏和子程序,才能掌握程序的编制方法。
2.宏的分析
本题中使用了下列宏,其作用如下:
SHOW:
用来指定地址的显示字符串,有一个地址参数
SET_P1:
设定光标位置,有一个可变参数a,作用是讲光标置于坐标(a,36)处,使用了BIOS中断10H的2号功能。
SET_P2:
将光标置于(12,2)处。
SET_P3:
将光标置于(1,30)处。
CLEAR:
清除整个屏幕,用BIOS中断10H的7号功能实现,范围是从坐标(0,0)到(24,79),将整个区域变为空白。
CLEAR1:
清除有半部分屏幕,清除范围从坐标(4,36)到(10,79),结果是擦出此区域的显示内容。
CLEAR2:
清除下半部分屏幕,清除范围是从坐标(12,0)到(24,79),结果是擦除此区域的显示内容。
NNWLINE:
回车换行。
SHOE_ITEM:
显示记录内容,执行后显示名称,然后依次显示4项功课成绩,各项成绩间空3个空格,最后换行。
这个宏包含的语句较多,如果每次都直接用语句实现非常冗长,使用宏后则主程序就很简洁,充分体现了使用宏的优点。
GETIN:
获取学生的信息,这也是一个使用频繁的宏,其中含有很多的指令,它带有ADDRS和COUNT2两个参数,ADDRS是存放信息的数据段位置,CIUNT2是接受的字符数。
子程序分析
下面详细分析程序中用的的主要的子程序。
(1)INSERT子程序
INSERT子程序的功能是录入一条记录。
首先保留现场入栈,然后DOS中断3D号功能打开FNAME指定的文件,然后宏GETIN清除屏幕右半部分的记录输入区域。
在记录的第一项处置光标,用GET_REC获取记录内容,用DOS中断42H号功能将指针移到文件末尾。
再用DOS中断40H号功能将放在BUFFER缓冲区的23个字节的内容写到文件中,接着关闭文件,重新设置光标位置在显示记录位置。
最后弹栈恢复现场。
(2)GET_REC子程序
GER_REC子程序的功能是获取新的记录内容。
首先用宏GETIN获取学生的姓名,放入BUFF2中,最多15个字符,如果遇到回车键则提前结束。
再用循环方式将BUFFER2中的15个字符送到BUFFER1中。
然后用宏SET_P1将光标置于数学成绩输入项后,等待键盘输入。
输入的成绩,先放在BUER2中,然后加到BUFFER1中的姓名后面。
输入为2个字符后遇到回车键提前结束。
接着用同样的方法输入英语成绩,计算机成绩和中文成绩。
完成后,这个程序就得到了一个记录的所有信息。
(3)OPENF子程序
OPENF是个一个非常简单的子程序。
它的作用是打开一个文件并把一个文件句柄保存在数据段的handle缓冲区中。
(4)QUERY子程序
QUERY是查询一条记录。
首先保留现场。
然后分别清除界面右上方和下边的区域。
打开FAME指定的文件并保留文件句柄。
将光标至于界面的下半空白部分开始处,用宏GETIN获取最多15个字符的输入,然后将BUFFER1中的内容与BUFFER2中进行比较,看是否相同。
如果不同,再继续向下从文件中读出23个字节比较,循环向下,直到相同或文件结束为止。
如果不同,则显示该条记录,然后关闭文件,恢复现场。
B:
MOVAH,3FH;读文件
MOVCX,23;读23个字节(记录长度)
MOVDX,OFFSETBUFFER2;放在BUFFER2中
INT21H
LEASI,BUFFER2
LEADI.BUFFER1
MOVCX,15;循环次数
C:
MOVAL,BYTEPTR[SI]
CMPAL,BYTEPTR[DI];比较BUFFER1和BUFFER2
JNZB;不同则转B
INCSI
INCD
LOOPC
(5)MODIFY子程序
MODIFY子程序的功能是修改记录。
先保护现场,然后清除右上部分的记录输入区域,接着打开文件。
用GET_REC子程序获取输入的记录信息,并存入BUFFER1中。
从打开的文件中读取一个记录的内容(23个字节)放在BUFFER2中。
比较记录前面的15个字节(姓名),如果不同,则读取下一个记录;如果相同,则回移一个记录的指针,回到刚才这条记录的位置(因为读取一个记录后,指针已移到下一条记录上)。
将放在BUFFER1中的输入的记录写到刚才这条记录在文件中的位置上,从而实现此记录的修改。
最后关闭程序,恢复现场。
(6)DELETE子程序
DELETE子程序的功能是删除一条记录。
首先保留现场,清除屏幕。
然后打开文件,保留文件句柄。
用宏GETIN获取15个字节的姓名字符,放在BUFFER1中。
读取一条记录(23个字节),放在BUFFER2中,然后和BUFFER1中内容比较,如果不同,读取下一条记录。
如果姓名相同,则把指针后移8个字符(4门功课所占空间),写入8个“0”字符。
关闭文件,恢复现场并退出。
(7)LIST子程序
LIST子程序的作用是显示文件中的记录。
首先清除记录输入区和显示区域。
然后显示记录字段的标题。
打开文件,保留文件句柄。
读取一条记录的内容放在BUFFER1中,并判断是否到了文件末尾,如果不是,则显示这条记录。
循环读取直到文件结束。
最后关闭程序,恢复现场。
(8)PRINT子程序
DELETE子程序的功能是打印文件中的记录。
用OPENF子程序打开文件。
读取一条记录,汇编语言提供了自定义数据结构的结构定义语句,可将不同的数据类型放在一个数据结构中,便于处理,在本程序中的记录就采用了结构定义语句。
这里读取记录也用了结构的方法。
接着用DOS中断21H的5号功能,逐字打印存放在BUFFER1中的所以字符。
一条记录打完后,打印回车符换行。
然后用同样方法继续读取下一条记录并打印,直到文件结束为止。
最后关闭文件退出。
(9)COT子程序
COT子程序的作用是统计各分数段小说人数,并简化程序,作为示例,本程序只统计记录数学各分数段的人数。
首先显示统计结果的标题:
maths<60<70<80<90<100。
然后打开文件。
读取记录,将记录的第16个字符(数学分数的高位)取出比较。
统计结果依次放在以BUFFER3开头的内存单元中,如果小于60,则将小于60的记录单元BUFFER3加一;若小于70,则将小于70的记录单元BUFFER3加一,即BUFFER3下一个地址单元内容加一,依次类推。
处理完后再读取下个记录,作同样处理,直到文件结束为止。
接着显示放在BUFFER3中的各分数段的人数的统计结果,最后关闭文件结束。
从程序中可以看出,统计时程序有个限制,本例每个分数段最多不能超过9个人。
操作说明
改程序除源程序外,还需要另一个存放记录的文件(此程序中使用的文件名为SCORE.TXT),但本程序并没有创建这个文件的功能。
要产生这个文件,可用记事本先做以一个空的文件名为SCORE.TXT的文件。
程序的运行与该文件的存放位置有关,位置是程序数据段的FNAME的值。
二者要保持一致,否则会因为找不到数据存放文件而出错。
程序运行时,在出现主菜单后,按1键,将显示学生的各科成绩;按i键,将执行录入功能,可以录入新的学生成绩;按M键,了修改学生成绩。
由于本程序时隔简单程序,所以在修改时,要输入学生的所有成绩,包括不要修改的成绩;按D键后,输入要删除的学生名,将使其成绩全为0;按Q键后,输入要查询的学生的姓名,键显示其各科成绩;按C键将显示数学成绩的分段统计结果。
以上功能在运行时可以单独实现(即在进入主菜单后,单击功能键选中该功能进行操作后程序会关闭。
但要运行其他功能,则要重新进入主菜单单击别的功能键,即每次只能运行一项功能)。
要特别说明的是,本程序住一套目的是验证汇编程序实现的数据记录操作功能,为使程序不至于郭长,减少篇幅,因此程序处理会很简单。
程序中没有错误处理程序,如果输入错误,如按退格键将会出错,因此输入时要注意补要输错。
程序代码
datasegment
mess1db'studentgrademanagementsystem',0ah,0dh,'$'
mess2db'thisismainmenu',0ah,0dh,'$'
mess3db'insert(i)pleaseinput:
',0ah,0dh,'$'
mess4db'modify(m)name:
',0ah,0dh,'$'
mess5db'delete(d)maths:
',0ah,0dh,'$'
mess6db'query(q)english:
',0ah,0dh,'$'
mess7db'count(c)computer:
',0ah,0dh,'$'
mess8db'print(p)chinese:
',0ah,0dh,'$'
mess9db'exit(e)',0ah,0dh,'$'
mess10db'**********************************************************$'
mess11db'nameMaEnCoCh',0ah,0dh,'$'
mess13db'list(l)',0ah,0dh,'$'
mess12db'maths<60<70<80<90<100',0ah,0dh,'$'
err1db'thereisnotthisstudent$'
err2db'fileclosewrong$'
fnamedb"d:
\masm\score.txt";记录分数文件的路径和文件名。
buffer1db23dup(?
)
buffeerdb0ah,0dh,'$'
buffer2db30dup(?
)
buffer3db8dup('0')
countdb5
handledw?
deldb8dup('0')
xdb?
dataends
scorestruc;定义记录结构
namesdb15dup('')
mathsdb0,0
englishdb0,0
computerdb0,0
chinesedb0,0
scoreends
showmacroaddrs;显示字符串
leadx,addrs
movah,9
int21h
endm
set_p1macroa;设光标于(a,36)
movah,2
movdh,a
movdl,36
movbh,0
int10h
endm
set_p2macro;设光标于(12,2)
movah,2
movdh,12
movdl,2
movbh,0
int10h
endm
set_p3macro;设光标于(1,30)
movah,2
movdh,1
movdl,30
movbh,0
int10h
endm
clearmacro;清整个屏幕
moval,0
movcl,0
movch,0
movdh,24
movdl,79
movbh,7
movah,6
int21h
endm
clear1macro;清右上记录输入区
moval,0
movbh,7
movch,4
movcl,36
movdh,10
movdl,79
movah,6
int10h
endm
clear2macro;清下半部分记录显示区
moval,0
movbh,7
movch,12
movcl,0
movdh,24
movdl,79
int10h
endm
newlinemacro;回车换行
pushax
pushdx
movdl,0dh
movah,2
int21h
movdl,0ah
movah,2
int21h
popdx
popax
endm
show_itemmacroaddrs;在指定位置显示记录
localiloop,w10
pushbx
pushcx
movbx,0
iloop:
movdl,addrs[bx];显字符串
movah,2
int21h
incbx
cmpbx,15
jliloop
movcx,4
w10:
movdl,''
movah,2
int21h
movdl,''
movah,2
int21h
movdl,''
movah,2
int21h
movdl,addrs[bx]
movah,2
int21h
incbx
movdl,addrs[bx]
movah,2
int21h
incbx
loopw10
newline
popcx
popbx
endm
getinmacroaddrs,count2;从键盘获取信息
localzeroit,lp,input_end,exit
pushbx
pushax
movbx,0
zeroit:
movaddrs[bx],''
incbx
cmpbx,15
jlzeroit
movbx,0
lp:
movah,1
int21h
cmpal,0ah
jzinput_end
cmpal,0dh
jzinput_end
movaddrs[bx],al
incbx
cmpbx,count2
jllp
input_end:
cmpal,0dh
jzexit
cmpal,0ah
jzexit
movah,7
int21h
jmpinput_end
exit:
popax
popbx
endm
codesegment
mainprocfar
assumecs:
code,ds:
data,es:
data
start:
movax,data
movds,ax
movah,0;设显示模式80*25
moval,3
int10h
clear
showmess1
showmess2
showmess13
showmess3
showmess4
showmess5
showmess6
showmess7
showmess8
showmess9
newline
showmess10
set_p3
w:
movah,7
int21h
cmpal,'i'
jnzn1
callinsert
jmpw
n1:
cmpal,'m'
jnzn2
callmodify
jmpw
n2:
cmpal,'d'
jnzn3
calldelete
jmpw
n3:
cmpal,'q'
jnzn4
callquery
jmpw
n4:
cmpal,'c'
jnzn5
callcot
jmpw
n5:
cmpal,'p'
jnzn6
callprint
jmpw
n6:
cmpal,'l'
jnzn7
calllist
jmpw
n7:
cmpal,'e'
jzexitf
jmpw
exitf:
movah,4ch
int21h
ret
mainendp
insertprocnear
pushax
pushbx
pushcx
pushdx
movdx,offsetfname
moval,2
movah,3dh;打开文件
int21h
movbx,ax
clear1
set_p14
callget_rec
movcx,0;指针移到文件尾
movdx,0
moval,2
movah,42h
int21h
movcx,23;写文件
movdx,offsetbuffer1
movah,40h
int21h
movah,3eh;关闭文件
int21h
set_p3
popdx
popcx
popbx
popax
ret
insertendp
get_recprocnear
pushax
pushbx
getinbuffer2,15;输入姓名
movbx,0
movcx,15
continue:
moval,buffer2[bx]
movbuffer1[bx],al
incbx
loopcontinue
set_p15
getinbuffer2,2;输入数学成绩
moval,buffer2
movbuffer1[bx],al
incbx
moval,buffer2+1
movbuffer1[bx],al
incbx
set_p16
getinbuffer2,2;输入英语成绩
moval,buffer2
movbuffer1[bx],al
incbx
moval,buffer2+1
movbuffer1[bx],al
incbx
set_p17
getinbuffer2,2;输入计算机成绩
moval,buffer2
movbuffer1[bx],al
incbx
moval,buffer2+1
movbuffer1[bx],al
incbx
set_p18
getinbuffer2,2;输入语文成绩
moval,buffer2
movbuffer1[bx],al
incbx
moval,buffer2+1
movbuffer1[bx],al
incbx
popbx
popax
ret
get_recendp
openfprocnear;打开文件
movdx,offsetfname
moval,02
movah,3dh
int21h
movhandle,ax
ret
openfendp
queryprocnear;查询记录
pushax
pushbx
pushcx
pushdx
clear1
clear2
movdx,offsetfname
moval,2
movah,3dh;打开文件
int21h
movbx,ax
set_p2
getinbuffer1,15;取姓名到buffr1中
leadx,mess11
movah,9
int21h
b:
movah,3fh;读文件
movcx,23;读23个字节(记录长度
movdx,offsetbuffer2;放在buffer2中
int21h
leasi,buffer2
leadi,buffer1
movcx,15;循环次数
c:
moval,byteptr[si]
cmpal,byteptr[di];比较buffer1和buffer2
jnzb;不同则转b
incsi
incdi
loopc
mov[buffer2+23],'$'
show_itembuffer2
movah,3eh
int21h
popdx
popcx
popbx
popax
ret
queryendp
modifyprocnear;修改记录
pushax
pushbx