学生成绩的统计课程设计-大学毕业设计.doc
课 程 设 计 课程名称 微机原理课程设计 题目名称 学生成绩的统计 学生学院 应用数学学院 专业班级 12信息安全2班 学 号 学生姓名 指导教师 2015 年 1 月 2 日18一、实验内容31.实验任务32.构思猜想3二、 实验设计31. 实验工具:MASM32、ResEd32. 实验过程42.1.图形设计42.2.应用程序代码52.3.程序资源的准备91) 修改Var.bat的地址92) 修改MakeFile103) 生成RC文件104) 生成OBJ文件115) 生成EXE程序123. 实验结果13三、 实验完整代码14四、 实验心得体会18(1) 本实验程序缺点18(2) 本实验程序优点18(3) 开发心得体会18一、实验内容1.实验任务输入十个学生某门课的成绩,统计低于60分,6069分,7079分,8089分,9099分和100分的人数,并输出统计结果。要求学生成绩的输入和统计结果的输出使用图形界面。2.构思猜想成绩统计是用于统计学生成绩的的简单的应用程序,所以正常的成绩统计程序,不能局限于统计一个固定人数(或不可变的),因为如果固定人数的话,当我们要用于不同的班级或专业时,对于不同的人数我们要做更多重复的操作,而造成无谓了人员或者资源的浪费。因此一个成绩统计软件必须要能应用于不同人数,而且能将统计结果呈现出来的。二、 实验设计1. 实验工具:MASM32、ResEd(1)MASM32:MASM32并非是指Microsoft的MASM宏汇编器。MASM32是一个由个人开发的包含了不同版本工具组建的汇编开发工具包。它的汇编编译器是MASM6.0以上版本中的Ml.exe,资源编译器是Microsoft Visual Studio中的Rc.exe,32位链接器是Microsoft Visual Studio中的Link.exe,同时包含有其他的一些如Lib.exe和DumpPe.exe等工具。本实验主要通过MASM开发环境,使我们的代码生成EXE。(2)ResEd:ResEd 是一个图形界面编辑工具,它不但可以用来编写程序所图形界面(如修改图标、菜单、鼠标。版本信息等),还支持了对exe、 dll等执行文件内的资源(图标、菜单、鼠标指针、位图、版本信息)等进行修改、替换。本程序不适用VC+的MFC设计程序的图形界面,因为VC+是被其开发者封装过的开发工具,里面的工作空间与开发工具本身的内部指令有关,因此,若用MFC生成的图形界面然后再取其生成RC文件,里面则会混淆许多我们不知的且对我们应用无用的代码段。使用ResEd,其本身是一个只用来设计图形界面的软件,负责的只是一个界面设计块,不用考虑该图形界面是否能成为应用或者被开发者如何使用,其生成的RC文件,只包含必要的控件的代码和设定,这让我们开发的时候能够更加的清晰且避免许多不必要的错误。2. 实验过程 2.1.图形设计使用ResEd设计我们需要的图形图一:图二:然后按“Ctrl+S”对我们的图形界面进行保存操作,然后就能生成(我取名为Rengar,名字又用户自行定义)Rengar.rc,我们右键文件“编辑”打开文件,这能清晰的看到我们的rc文件,并且在文件最顶端加上一句“#include<resource.h>”,如图示2.2.应用程序代码这里我使用的是老师给出的代码作为模板,添加修改自己的代码进去,完整代码在下面会给出,这里我们只对部分关键代码进行解析1) 我们将刚刚生成的RC文件打开后,将我们控件的ID放进模板中控件ID部分:放入模板的Equ定义中:2) 本程序录入成绩与导出成绩结果是在两个不同的对话框上,因此我们要对两个对话框进行设定结果对话框代码:_ProcDlgMainlprocuses ebx edi esi, hWnd,wMsg,wParam,lParam local szBuffer5:bytemoveax,wMsg.ifeax = WM_CLOSEinvokeEndDialog,hWnd,NULL.elseifeax = WM_INITDIALOGmov esi,failinvoke SetDlgItemInt,hWnd,IDC_EDT2,esi,TRUEmov esi,sixtyinvoke SetDlgItemInt,hWnd,IDC_EDT3,esi,TRUEmov esi,seventyinvoke SetDlgItemInt,hWnd,IDC_EDT4,esi,TRUEmov esi,eightyinvoke SetDlgItemInt,hWnd,IDC_EDT5,esi,TRUEmov esi,ninetyinvoke SetDlgItemInt,hWnd,IDC_EDT6,esi,TRUEmov esi,hundredinvoke SetDlgItemInt,hWnd,IDC_EDT7,esi,TRUE.elseifeax = WM_COMMAND.ifax = IDCANCELinvokeEndDialog,hWnd,NULL.endif.elsemoveax,FALSEret.endifmoveax,TRUEret_ProcDlgMainlendp主界面对话框代码:_ProcDlgMainprocuses ebx edi esi, hWnd,wMsg,wParam,lParam local szBuffer2:bytemoveax,wMsg.ifeax = WM_CLOSEinvokeEndDialog,hWnd,NULL.elseifeax = WM_INITDIALOGinvokeLoadIcon,hInstance,ICO_MAINinvokeSendMessage,hWnd,WM_SETICON,ICON_BIG,eax.elseifeax = WM_COMMANDmoveax,wParam.ifax = IDCANCELinvokeEndDialog,hWnd,NULL .elseif ax = IDC_BTN1; invoke GetDlgItemInt,hWnd,IDC_EDT1,szBuffer,TRUE mov ebx ,index mov scoreebx*(type score),eaxinc indexinc ebxmov index,ebxmov ecx, lengthof scoremov eax,0.elseif ax = IDOKmov fail , 0mov sixty, 0mov seventy, 0mov eighty, 0mov ninety,0mov hundred, 0mov ecx,10again:.if scoreebx*(type score)<60inc fail.elseif scoreebx*(type score)<70inc sixty.elseif scoreebx*(type score)<80inc seventy.elseif scoreebx*(type score)<90inc eighty.elseif scoreebx*(type score)<100inc ninety.elseif scoreebx*(type score)=100inc hundred.endifinc ebx;.if ebx<10loop again ;.endif ;.endifInvoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,offset _ProcDlgMainl,NULL /这句的作用是我们调出第二个对话框(结果对话框).endif.elsemoveax,FALSEret.endifmoveax,TRUEret_ProcDlgMainendp主界面代码中,我的again函数里面我采用了ecx寄存器计数,这是我实现对应不同人数情况统计的关键方法,ecx寄存的立即数就是我们要统计的人数的范围。2.3.程序资源的准备把我们制作的.asm和RC文件、var.bat、MakeFile放在同一个文件夹内,然后在放进MASM32目录里1) 修改Var.bat的地址我的MASM安装在C盘,因此第三行修改为“C:Masm32”2) 修改MakeFile打开MakeFile,将里面的“NAME=”加上你的程序的名字3) 生成RC文件打开CMD控制台,输入“cd (scr)”再按回车键进入文件夹,其中“(scr)”为你的rc所在文件夹地址,如图然后在按图内操作,生成res文件4) 生成OBJ文件操作如图:然后则生成我的的OBJ文件:5) 生成EXE程序我们需要用Link指令将OBJ和RES文件连接起来生成一个带图形界面的EXE文件,指令是“subsystem:windows OBJ RES”操作如图:我们的成绩统计程序就出来了:3. 实验结果主界面:结果界面每统计一次,左上角的值则会少一次,该值则为ecx的值。三、 实验完整代码.386.model flat, stdcalloption casemap :none;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Include 文件定义;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>includewindows.incincludeuser32.incincludelibuser32.libincludekernel32.incincludelibkernel32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Equ 等值定义;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IDD_MFC2_DIALOG equ 1100 IDC_BTN1 equ 1001 IDC_EDT1 equ 1002 IDOK equ 1 IDCANCEL equ 2 IDD_DIALOG1 equ 1000 IDC_EDT2 equ 1001 IDC_EDT3 equ 1002 IDC_EDT4 equ 1003 IDC_EDT5 equ 1004 IDC_EDT6 equ 1005 IDC_EDT7 equ 1006ICO_MAIN equ 1;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 数据段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.data?hInstancedd?.datascoredword0,0,0,0,0,0,0,0,0,0faildword 0sixtydword 0seventydword0eightydword0ninetydword0hundreddword0indexdword0;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 代码段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.code;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_ProcDlgMainlprocuses ebx edi esi, hWnd,wMsg,wParam,lParam local szBuffer5:bytemoveax,wMsg.ifeax = WM_CLOSEinvokeEndDialog,hWnd,NULL.elseifeax = WM_INITDIALOGmov esi,failinvoke SetDlgItemInt,hWnd,IDC_EDT2,esi,TRUEmov esi,sixtyinvoke SetDlgItemInt,hWnd,IDC_EDT3,esi,TRUEmov esi,seventyinvoke SetDlgItemInt,hWnd,IDC_EDT4,esi,TRUEmov esi,eightyinvoke SetDlgItemInt,hWnd,IDC_EDT5,esi,TRUEmov esi,ninetyinvoke SetDlgItemInt,hWnd,IDC_EDT6,esi,TRUEmov esi,hundredinvoke SetDlgItemInt,hWnd,IDC_EDT7,esi,TRUE.elseifeax = WM_COMMAND.ifax = IDCANCELinvokeEndDialog,hWnd,NULL.endif.elsemoveax,FALSEret.endifmoveax,TRUEret_ProcDlgMainlendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_ProcDlgMainprocuses ebx edi esi, hWnd,wMsg,wParam,lParam local szBuffer2:bytemoveax,wMsg.ifeax = WM_CLOSEinvokeEndDialog,hWnd,NULL.elseifeax = WM_INITDIALOGinvokeLoadIcon,hInstance,ICO_MAINinvokeSendMessage,hWnd,WM_SETICON,ICON_BIG,eax.elseifeax = WM_COMMANDmoveax,wParam.ifax = IDCANCELinvokeEndDialog,hWnd,NULL .elseif ax = IDC_BTN1; invoke GetDlgItemInt,hWnd,IDC_EDT1,szBuffer,TRUE mov ebx ,index mov scoreebx*(type score),eaxinc indexinc ebxmov index,ebxmov ecx, lengthof scoremov eax,0.elseif ax = IDOKmov fail , 0mov sixty, 0mov seventy, 0mov eighty, 0mov ninety,0mov hundred, 0mov ecx,10again:.if scoreebx*(type score)<60inc fail.elseif scoreebx*(type score)<70inc sixty.elseif scoreebx*(type score)<80inc seventy.elseif scoreebx*(type score)<90inc eighty.elseif scoreebx*(type score)<100inc ninety.elseif scoreebx*(type score)=100inc hundred.endifinc ebxloop again invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,offset _ProcDlgMainl,NULL.endif.elsemoveax,FALSEret.endifmoveax,TRUEret_ProcDlgMainendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>start:invokeGetModuleHandle,NULLmovhInstance,eaxinvokeDialogBoxParam,hInstance,IDD_MFC2_DIALOG,NULL,offset _ProcDlgMain,NULLinvokeExitProcess,NULL;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>endstart四、 实验心得体会(1) 本实验程序缺点对细节方面处理不够好,例如让用户自定义ecx的大小不能在开始统计前直接在主界面先进行设定,点击录入后没有响应类似于MassageBox那样的提示或者Label提示录入成功,因为学艺不精,不知道如何使用汇编语言进行以上操作,望体谅。(2) 本实验程序优点能够适应不同人数的班级的成绩统计,不局限与一个界面的有限空间,ecx足够大时,能做到“无限”录入数据,而且界面简洁,减少空间。(3) 开发心得体会在刚拿到此课程设计任务的时候,对于刚接触汇编语言不久的我来说无疑是一个“艰巨”的任务,因为只学到了基础的知识且没有实际的汇编开发经验,所以心里莫名的慌。所以在进行开发之前,我在百度查阅来许多关于汇编的资料,还有类似的应用程序的资料,但我发现他们的共同点都是局限于界面的控件数量的统计。因为之前是有一定的C+/C/JAVA的开发经验,所以思想上,对用户来说是十分的不便利的软件,因此就定下了我要做的软件的方向“无限”录入数据。但是,对于汇编语言基础学的不深的我来说,靠着C+/JAVA的思想是不够的,因为要实现相应的功能,则需要写出对应的汇编代码才能实现,因此花了很长时间通过各个渠道(如中国知网、万维网等)查阅资料及汇编语言的教程,最终才形成本次实验的我的应用程序。虽然对于程序本身来说,它并不是完成品,只能算是一个半成品,但对于我来说,它就是我现有知识的完成品。对于应用程序的开发,并不是刚开发出来就是一个完美无瑕的程序,需要后继的不断改进,才能使程序更加的完整、更加的完美。