1、1学 生 成 绩 管 理 系 统目录设计内容 2设计目的 2设计要求 2设计分析 2子程序分析 7操作说明 10程序代码 11总结 30参考文献 302设计内容设计一个学生成绩管理程序,要求能实现以下功能:1) 各科成绩的录入,修改和删除。2) 按姓名查询每个学生各门课的成绩。3) 显示查询结果。4) 统计个分数段的人数。5)打印学生成绩。设计目的用汇编数据的录入、修改和删除操作。设计要求学习如何用汇编语言进行数据处理。设计分析1.总体结构整个程序采用主程序调用子程序的方法。主程序完成菜单的显示,子程序完成一个独立功能方法的实现。各子程序的实现方法简要描述如下:1)设计 INSERT(录入)子
2、程序,先打开文件 SCORE.TXT,并置文件指针到文件尾,然后调用REC 子程序接受用户的输入,再把用户的输入写入文件,最后关闭文件返回主程序。2)设计 Delete(删除)子程序,先打开文件,再调用宏 GETIN 得到要删除的学生的姓3名,然后读文件中的记录,直到其记录的名字与所输入的名字相同为止,把文件指针后退8 个字符(即 4 门课成绩所占的空间) ,写入 8 个“0 ”字符,关闭文件返回主程序。3)设计 List(浏览)子程序时,先打开文件,然后读一个记录,并通过调用宏SHOW_ITEM 将其显示到屏幕上,入文件指针没有到达文件尾,则继续读记录并显示,当指针到达文件尾时,则关闭文件返
3、回主程序。4)设计 Modify(修改)子程序时,先打开文件 SCORE.TXT,通用 GER_REC 得到要修改的记录,然后读文件中的记录,并与用户输入的记录做比较(只比较记录中的名字部分) ,若不同则吨下一条记录,若相同则将文件指针后退 23 个字符(一个记录为 23 个字符的长度) ,然后把用户输入的记录写入文件,最后关闭文件返回主程序。5)设计 Count(统计)子程序时,先打开文件,然后读记录,比较记录的第 16 个字符,数学成绩的高位) ,并统计,直到文件指针到达文件尾,最后关闭文件调用宏SHOW_ITEM 显示统计结果,返会主程序。6)设计 Query(查询)子程序时,先打开文件
4、,通过调用宏 GETIN 得到要查找学生的姓名,然后读文件记录,并同要查找的学生姓名比较,若相同则输出,若不同继续读文件记录,最后显示查询结果,关闭文件返回程序。另外还有打印的分数段人数统计,这些结合后面的子程序功能分析做详细介绍。图 1 是本设计显示记录的界面图 1 学生成绩管理系统界面4入口程序流程图如图 2 所示YNYNA) List 流程图 B) Insert 流程图打开文件读一个记录读错?文件尾?显示记录显示错误信息关闭文件返回入口打开文件置指针到文件尾从终端接收用户输入的记录记录写入文件关闭文件返回5Y YN NNYN Y入口打开文件读一个记录是否为所寻找的记录显示记录关闭文件返回
5、入口打开文件读一个记录是否为要修改的记录文件指针后退一个记录写入修改记录并关闭文件返回入口打开文件读一个记录对数学成绩分段并统计指针到达文件尾显示统计结果关闭文件返回入口打开文件接收被删除记录的学生姓名读一条记录姓名相同?删除记录返回文件返回6YNYNYNYNYNYNNY在大型的程序中,为了使程序清晰、可读性好,一般会大量使用宏和子程序,因此,充分了解这些宏和子程序,才能掌握程序的编制方法。开始显示菜单输入一个字符是 L是 Q是 D是 M是 C是 I是 E结束调用 Iist 子程序调用 Query 子程序调用 Delete 子程序调用 Modify 子程序调用 Count 子程序调用 Inse
6、rt 子程序72.宏的分析本题中使用了下列宏,其作用如下: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) ,结果是擦出此区域的显示内容。CLEA
7、R2 : 清除下半部分屏幕,清除范围是从坐标(12, 0)到(24 ,79) ,结果是擦除此区域的显示内容。NNWLINE : 回车换行。SHOE_ITEM :显示记录内容,执行后显示名称,然后依次显示 4 项功课成绩,各项成绩间空 3 个空格,最后换行。这个宏包含的语句较多,如果每次都直接用语句实现非常冗长,使用宏后则主程序就很简洁,充分体现了使用宏的优点。GETIN : 获取学生的信息,这也是一个使用频繁的宏,其中含有很多的指令,它带有ADDRS 和 COUNT2 两个参数, ADDRS 是存放信息的数据段位置, CIUNT2 是接受的字符数。子程序分析下面详细分析程序中用的的主要的子程序
8、。(1 ) INSERT 子程序INSERT 子程序的功能是录入一条记录。首先保留现场入栈,然后 DOS 中断 3D 号功能打开 FNAME 指定的文件,然后宏 GETIN清除屏幕右半部分的记录输入区域。在记录的第一项处置光标,用 GET_REC 获取记录内容,用 DOS 中断 42H 号功能将指针移到文件末尾。再用 DOS 中断 40H 号功能将放在 BUFFER 缓冲区的 23 个字节的内容写到文件中,接着8关闭文件,重新设置光标位置在显示记录位置。最后弹栈恢复现场。(2 ) GET_REC 子程序GER_REC 子程序的功能是获取新的记录内容。首先用宏 GETIN 获取学生的姓名,放入
9、BUFF2 中,最多 15 个字符,如果遇到回车键则提前结束。再用循环方式将 BUFFER2 中的 15 个字符送到 BUFFER1 中。然后用宏 SET_P1 将光标置于数学成绩输入项后,等待键盘输入。输入的成绩,先放在BUER2 中,然后加到 BUFFER1 中的姓名后面。输入为 2 个字符后遇到回车键提前结束。接着用同样的方法输入英语成绩,计算机成绩和中文成绩。完成后,这个程序就得到了一个记录的所有信息。(3 ) OPENF 子程序OPENF 是个一个非常简单的子程序。它的作用是打开一个文件并把一个文件句柄保存在数据段的 handle 缓冲区中。(4 ) QUERY 子程序QUERY 是
10、查询一条记录。首先保留现场。然后分别清除界面右上方和下边的区域。打开 FAME 指定的文件并保留文件句柄。将光标至于界面的下半空白部分开始处,用宏 GETIN 获取最多 15 个字符的输入,然后将 BUFFER1 中的内容与 BUFFER2 中进行比较,看是否相同。如果不同,再继续向下从文件中读出 23 个字节比较,循环向下,直到相同或文件结束为止。如果不同,则显示该条记录,然后关闭文件,恢复现场。B: MOV AH , 3FH ;读文件MOV CX , 23 ;读 23 个字节(记录长度)MOV DX, OFFSET BUFFER2 ;放在 BUFFER2 中INT 21HLEA SI ,
11、BUFFER2LEA DI .BUFFER1MOV CX,15 ;循环次数C: MOV AL , BYTE PTRSI9CMP AL , BYTE PTR DI ;比较 BUFFER1 和 BUFFER2JNZ B ;不同则转 BINC SIINC DLOOP C(5 ) MODIFY 子程序MODIFY 子程序的功能是修改记录。先保护现场,然后清除右上部分的记录输入区域,接着打开文件。用 GET_REC 子程序获取输入的记录信息,并存入 BUFFER1 中。从打开的文件中读取一个记录的内容(23 个字节)放在 BUFFER2 中。比较记录前面的 15 个字节(姓名) ,如果不同,则读取下一个
12、记录;如果相同,则回移一个记录的指针,回到刚才这条记录的位置(因为读取一个记录后,指针已移到下一条记录上) 。将放在 BUFFER1 中的输入的记录写到刚才这条记录在文件中的位置上,从而实现此记录的修改。最后关闭程序,恢复现场。(6)DELETE 子程序DELETE 子程序的功能是删除一条记录。首先保留现场,清除屏幕。然后打开文件,保留文件句柄。用宏 GETIN 获取 15 个字节的姓名字符,放在 BUFFER1 中。读取一条记录(23 个字节) ,放在 BUFFER2 中,然后和 BUFFER1 中内容比较,如果不同,读取下一条记录。如果姓名相同,则把指针后移 8 个字符(4 门功课所占空间
13、) ,写入 8 个“0”字符。关闭文件,恢复现场并退出。(7)LIST 子程序LIST 子程序的作用是显示文件中的记录。首先清除记录输入区和显示区域。然后显示记录字段的标题。打开文件,保留文件句柄。读取一条记录的内容放在 BUFFER1 中,并判断是否到了文件末尾,如果不是,则显示这条记录。循环读取直到文件结束。最后关闭程序,恢复现场。(8)PRINT 子程序DELETE 子程序的功能是打印文件中的记录。用 OPENF 子程序打开文件。读取一条记录,汇编语言提供了自定义数据结构的结构10定义语句,可将不同的数据类型放在一个数据结构中,便于处理,在本程序中的记录就采用了结构定义语句。这里读取记录
14、也用了结构的方法。接着用 DOS 中断 21H 的 5 号功能,逐字打印存放在 BUFFER1 中的所以字符。一条记录打完后,打印回车符换行。然后用同样方法继续读取下一条记录并打印,直到文件结束为止。最后关闭文件退出。(9)COT 子程序COT 子程序的作用是统计各分数段小说人数,并简化程序,作为示例,本程序只统计记录数学各分数段的人数。首先显示统计结果的标题:maths60708090100。然后打开文件。读取记录,将记录的第 16 个字符(数学分数的高位)取出比较。统计结果依次放在以 BUFFER3 开头的内存单元中,如果小于 60,则将小于 60 的记录单元BUFFER3 加一;若小于
15、70,则将小于 70 的记录单元 BUFFER3 加一,即 BUFFER3 下一个地址单元内容加一,依次类推。处理完后再读取下个记录,作同样处理,直到文件结束为止。接着显示放在 BUFFER3 中的各分数段的人数的统计结果,最后关闭文件结束。从程序中可以看出,统计时程序有个限制,本例每个分数段最多不能超过 9 个人。操作说明改程序除源程序外,还需要另一个存放记录的文件(此程序中使用的文件名为SCORE.TXT),但本程序并没有创建这个文件的功能。要产生这个文件,可用记事本先做以一个空的文件名为 SCORE.TXT 的文件。程序的运行与该文件的存放位置有关,位置是程序数据段的 FNAME 的值。
16、二者要保持一致,否则会因为找不到数据存放文件而出错。程序运行时,在出现主菜单后,按 1 键,将显示学生的各科成绩;按 i 键,将执行录入功能,可以录入新的学生成绩;按 M 键,了修改学生成绩。由于本程序时隔简单程序,所以在修改时,要输入学生的所有成绩,包括不要修改的成绩;按 D 键后,输入要删除的学生名,将使其成绩全为 0;按 Q 键后,输入要查询的学生的姓名,键显示其各科成绩;按 C 键将显示数学成绩的分段统计结果。以上功能在运行时可以单独实现(即在进入主菜单后,单击功能键选中该功能进行操11作后程序会关闭。但要运行其他功能,则要重新进入主菜单单击别的功能键,即每次只能运行一项功能) 。要特
17、别说明的是,本程序住一套目的是验证汇编程序实现的数据记录操作功能,为使程序不至于郭长,减少篇幅,因此程序处理会很简单。程序中没有错误处理程序,如果输入错误,如按退格键将会出错,因此输入时要注意补要输错。程序代码data segmentmess1 db student grade management system,0ah,0dh,$mess2 db this is main menu,0ah,0dh,$mess3 db insert (i) please input:,0ah,0dh,$ mess4 db modify (m) name :,0ah,0dh,$ mess5 db delete
18、(d) maths :,0ah,0dh,$mess6 db query (q) english :,0ah,0dh,$mess7 db count (c) computer:,0ah,0dh,$mess8 db print (p) chinese :,0ah,0dh,$mess9 db exit (e),0ah,0dh,$mess10 db *$mess11 db name Ma En Co Ch,0ah,0dh,$mess13 db list (l),0ah,0dh,$mess12 db maths 60 70 80 90 100,0ah,0dh,$err1 db there is not
19、this student$err2 db file close wrong$fname db “d:masmscore.txt“ ;记录分数文件的路径和文件名。buffer1 db 23 dup(?)buffeer db 0ah,0dh,$buffer2 db 30 dup(?)buffer3 db 8 dup(0)12count db 5handle dw ?del db 8 dup(0)x db ?data endsscore struc ;定义记录结构names db 15 dup( )maths db 0,0english db 0,0computer db 0,0chinese db
20、 0,0score endsshow macro addrs ;显示字符串lea dx,addrsmov ah,9int 21hendmset_p1 macro a ;设光标于(a,36)mov ah,2mov dh,amov dl,36mov bh,0int 10hendmset_p2 macro ;设光标于(12,2)mov ah,2mov dh,12mov dl,2mov bh,0int 10h13endmset_p3 macro ;设光标于(1,30)mov ah,2mov dh,1mov dl,30mov bh,0int 10hendmclear macro ;清整个屏幕 mov a
21、l,0mov cl,0mov ch,0mov dh,24mov dl,79mov bh,7mov ah,6int 21hendmclear1 macro ;清右上记录输入区 mov al,0mov bh,7mov ch,4mov cl,36mov dh,10mov dl,79mov ah,6int 10hendmclear2 macro ;清下半部分记录显示区mov al,014mov bh,7mov ch,12mov cl,0mov dh,24mov dl,79int 10hendmnewline macro ;回车换行push axpush dxmov dl,0dhmov ah,2int
22、21hmov dl,0ahmov ah,2int 21hpop dxpop axendmshow_item macro addrs ;在指定位置显示记录local iloop,w10push bxpush cxmov bx,0iloop: mov dl,addrsbx ;显字符串mov ah,2int 21hinc bxcmp bx,15jl iloop15mov cx,4w10: mov dl, mov ah,2int 21hmov dl, mov ah,2int 21hmov dl, mov ah,2int 21hmov dl,addrsbxmov ah,2int 21hinc bxmov
23、 dl,addrsbxmov ah,2int 21hinc bxloop w10newlinepop cxpop bxendmgetin macro addrs,count2 ;从键盘获取信息local zeroit,lp,input_end,exitpush bxpush axmov bx,0zeroit: mov addrsbx, inc bx16cmp bx,15jl zeroitmov bx,0lp: mov ah,1int 21hcmp al,0ahjz input_endcmp al,0dhjz input_endmov addrsbx,alinc bxcmp bx,count2j
24、l lpinput_end: cmp al,0dhjz exitcmp al,0ahjz exitmov ah,7int 21hjmp input_endexit: pop axpop bxendmcode segmentmain proc farassume cs:code,ds:data,es:datastart: mov ax,datamov ds,axmov ah,0 ;设显示模式 80*25mov al,317int 10hclearshow mess1show mess2show mess13show mess3show mess4show mess5show mess6show
25、mess7show mess8show mess9newlineshow mess10set_p3w: mov ah,7int 21hcmp al,ijnz n1 call insertjmp wn1: cmp al,mjnz n2call modifyjmp wn2: cmp al,djnz n3call deletejmp wn3: cmp al,q18jnz n4call queryjmp wn4: cmp al,cjnz n5call cotjmp wn5: cmp al,pjnz n6call printjmp wn6: cmp al,ljnz n7call listjmp wn7:
26、 cmp al,ejz exitfjmp wexitf: mov ah,4chint 21hretmain endpinsert proc nearpush axpush bxpush cxpush dxmov dx,offset fnamemov al,2mov ah,3dh ;打开文件19int 21hmov bx,axclear1set_p1 4call get_recmov cx,0 ;指针移到文件尾mov dx,0mov al,2mov ah,42hint 21hmov cx,23 ;写文件 mov dx,offset buffer1mov ah,40h int 21hmov ah,
27、3eh ;关闭文件int 21hset_p3pop dxpop cxpop bxpop axretinsert endpget_rec proc nearpush axpush bxgetin buffer2,15 ;输入姓名mov bx,0mov cx,15continue: mov al,buffer2bx20mov buffer1bx,alinc bxloop continueset_p1 5getin buffer2,2 ;输入数学成绩mov al,buffer2mov buffer1bx,alinc bxmov al,buffer2+1mov buffer1bx,alinc bxse
28、t_p1 6 getin buffer2,2 ;输入英语成绩mov al,buffer2mov buffer1bx,alinc bxmov al,buffer2+1mov buffer1bx,alinc bxset_p1 7getin buffer2,2 ;输入计算机成绩mov al,buffer2mov buffer1bx,alinc bxmov al,buffer2+1mov buffer1bx,alinc bxset_p1 8getin buffer2,2 ;输入语文成绩mov al,buffer221mov buffer1bx,alinc bxmov al,buffer2+1mov b
29、uffer1bx,alinc bxpop bxpop axretget_rec endpopenf proc near ;打开文件mov dx,offset fnamemov al,02mov ah,3dhint 21hmov handle,axretopenf endpquery proc near ;查询记录push axpush bxpush cxpush dxclear1clear2mov dx,offset fnamemov al,2mov ah,3dh ;打开文件int 21hmov bx,axset_p222getin buffer1,15 ;取姓名到 buffr1 中lea d
30、x,mess11mov ah,9int 21hb: mov ah,3fh ;读文件mov cx,23 ;读 23 个字节(记录长度mov dx,offset buffer2 ;放在 buffer2 中int 21hlea si,buffer2lea di,buffer1mov cx,15 ;循环次数c: mov al,byte ptrsi cmp al,byte ptrdi ;比较 buffer1 和 buffer2jnz b ;不同则转 binc siinc diloop cmov buffer2+23,$show_item buffer2mov ah,3ehint 21hpop dx po
31、p cxpop bxpop axretquery endpmodify proc near ;修改记录push axpush bx23push cxpush dxclear1set_p1 4mov dx,offset fnamemov al,2mov ah,3dhint 21hmov bx,axmov handle,axcall get_rec ;读取输入内容放在 buffer1read: mov dx,offset buffer2mov cx,23mov ah,3fh ;读文件,记录内容放在buffer2int 21hlea si,buffer2 ;比较姓名是否相同lea di,buffer
32、1mov cx,15c5: mov dl,byte ptrsi cmp dl,byte ptrdijnz readinc siinc diloop c5mov bx,handlemov ah,42h ;回移文件指针mov al,1mov cx,0ffffhmov dx,-2324int 21hmov cx,23mov dx,offset buffer1 mov ah,40h ;写入修改记录int 21hmov ah,3ehint 21hjmp exit2exit1: set_p2show err1 exit2: set_p3 pop dxpop cxpop bxpop axretmodify
33、endpdelete proc nearpush axpush bxpush cxpush dxclear1set_p1 4mov dx,offset fnamemov al,2mov ah,3dh ;打开文件int 21hmov bx,axmov handle,ax25getin buffer1,15 ;读取键盘输入放在 buffer1read5: mov dx,offset buffer2mov cx,23mov ah,3fh ;从文件读记录放在 buffer2 中int 21hlea si,buffer2lea di,buffer1mov cx,15c6: mov dl,byte ptr
34、si cmp dl,byte ptrdijnz read5inc siinc diloop c6mov bx,handlemov ah,42h ;移文件指针mov al,1mov cx,0ffffhmov dx,-8int 21hmov cx,8mov dx,offset delmov ah,40h ;写文件int 21hmov ah,3eh ;关闭文件int 21hjmp exit6exit5: set_p2show err1 exit6: set_p3 26pop dxpop cxpop bxpop axretdelete endp list proc near ;列文件中记录push a
35、xpush bxpush cxpush dxclear1clear2set_p2show mess11mov dx,offset fnamemov al,2mov ah,3dh ;打开文件int 21hmov bx,axagain: mov dx,offset buffer1 ;读取记录mov cx,23mov ah,3fhint 21hcmp ax,0jz pshow_item buffer1jmp againp: mov ah,3eh ;关闭文件int 21h27set_p3pop dxpop cxpop bxpop axretlist endpprint proc nearpush ax
36、call openf ;打开文件mov cl,countmov ch,0read2: mov dx,offset buffer1mov cx,type scoremov ah,3fh ;读文件int 21hmov cx,23hmov bx,0next: mov ah,5mov dl,byte ptr buffer1bxint 21hinc bxloop nextmov ah,5mov dl,0dhint 21hdec xcmp x,0jnz read2mov bx,handle28mov ah,3ehint 21hpop axretprint endpcot proc ;统计成绩push ax
37、clear2set_p2show mess12mov dx,offset fnamemov ah,3dh ;打开文件int 21hmov bx,axmov handle,axread0: mov dx,offset buffer2mov cx,23mov ah,3fh ;读记录int 21hmov dl,buffer2+15cmp dl,6jl fivecmp dl,7jl sixcmp dl,8jl sevencmp dl,9jl eightinc buffer3+4jmp quit29eight: inc buffer3+3jmp quitseven: inc buffer3+2jmp q
38、uitsix: inc buffer3+1jmp quitfive: inc buffer3quit: cmp ax,0jnz read0mov cx,10a: mov dl, mov ah,2int 21hloop a mov bx,0 a0: mov dl,buffer3+bx ;显示统计结果mov ah,2int 21hinc bxmov dl, mov ah,2int 21hmov dl, mov ah,2int 21hcmp bx,5jnz a0mov bx,handlemov ah,3eh ;关闭文件30int 21hset_p3pop axretcot endpcode ends
39、end start总结此次课程设计需要考虑的功能很多,因此需要分模块来完成。每个组员负责一个模块,插入(insert )由水健负责,修改(modify)由张翔负责,删除( delete)由胡玉杰负责,查询(query )由肖大庆负责,统计(count)由王瀚负责,并非是每个人只管一块,而是互相配合,主要负责一部分,至于别的部分,那些不怎么太难就没有人专门负责了,而且人也没那么多。从这次课程设计中了解到分工合作的重要性,以后工作中遇到程序只可能比这个复杂,一个人很难独自完成,那就要需要到合作了。另外就是在课堂上学到的知识根本就不够,要做好一个程序必须多掌握一些书本外的相关知识。参考文献1、 沈美明,温冬婵。 IBM PC 汇编语言程序设计M 2 版 北京:清华大学出版社,20022、 孙德文。 微型计算机技术M 北京:高等教育出版社,20023、 赵雁南,温冬婵。 微型计算机系统与接口M 北京:清华大学出版社,20054、 裘雪红,李伯成,刘凯。 微型计算机原理及接口技术 M 西安:西安电子科技大学出版社,2007.35、 王成瑞等。汇编语言程序设计M 北京:高等教育出版社,2003