资源描述
课 程 设 计
课程名称 微机原理课程设计
题目名称 学生成绩的统计
学生学院 应用数学学院
专业班级 12信息安全2班
学 号
学生姓名
指导教师
2015 年 1 月 2 日
18
一、实验内容 3
1.实验任务 3
2.构思猜想 3
二、 实验设计 3
1. 实验工具:MASM32、ResEd 3
2. 实验过程 4
2.1.图形设计 4
2.2.应用程序代码 5
2.3.程序资源的准备 9
1) 修改Var.bat的地址 9
2) 修改MakeFile 10
3) 生成RC文件 10
4) 生成OBJ文件 11
5) 生成EXE程序 12
3. 实验结果 13
三、 实验完整代码 14
四、 实验心得体会 18
(1) 本实验程序缺点 18
(2) 本实验程序优点 18
(3) 开发心得体会 18
一、实验内容
1.实验任务
输入十个学生某门课的成绩,统计低于60分,60~69分,70~79分,80~89分,90~99分和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) 本程序录入成绩与导出成绩结果是在两个不同的对话框上,因此我们要对两个对话框进行设定
结果对话框代码:_ProcDlgMainl proc uses ebx edi esi, hWnd,wMsg,wParam,lParam
local @szBuffer[5]:byte
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
mov esi,[fail]
invoke SetDlgItemInt,hWnd,IDC_EDT2,esi,TRUE
mov esi,[sixty]
invoke SetDlgItemInt,hWnd,IDC_EDT3,esi,TRUE
mov esi,[seventy]
invoke SetDlgItemInt,hWnd,IDC_EDT4,esi,TRUE
mov esi,[eighty]
invoke SetDlgItemInt,hWnd,IDC_EDT5,esi,TRUE
mov esi,[ninety]
invoke SetDlgItemInt,hWnd,IDC_EDT6,esi,TRUE
mov esi,[hundred]
invoke SetDlgItemInt,hWnd,IDC_EDT7,esi,TRUE
.elseif eax == WM_COMMAND
.if ax == IDCANCEL
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMainl endp
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
主界面对话框代码:_ProcDlgMain proc uses ebx edi esi, hWnd,wMsg,wParam,lParam
local @szBuffer[2]:byte
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDCANCEL
invoke EndDialog,hWnd,NULL
.elseif ax == IDC_BTN1;
invoke GetDlgItemInt,hWnd,IDC_EDT1,@szBuffer,TRUE
mov ebx ,index
mov score[ebx*(type score)],eax
inc index
inc ebx
mov index,ebx
mov ecx, lengthof score
mov eax,0
.elseif ax == IDOK
mov fail , 0
mov sixty, 0
mov seventy, 0
mov eighty, 0
mov ninety,0
mov hundred, 0
mov ecx,10
again: .if score[ebx*(type score)]<60
inc [fail]
.elseif score[ebx*(type score)]<70
inc [sixty]
.elseif score[ebx*(type score)]<80
inc [seventy]
.elseif score[ebx*(type score)]<90
inc [eighty]
.elseif score[ebx*(type score)]<100
inc [ninety]
.elseif score[ebx*(type score)]==100
inc [hundred]
.endif
inc ebx
;.if ebx<10
loop again
;.endif
;.endif
Invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,offset _ProcDlgMainl,NULL //这句的作用是我们调出第二个对话框(结果对话框)
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
主界面代码中,我的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, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.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 1006
ICO_MAIN equ 1
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
.data
score dword 0,0,0,0,0,0,0,0,0,0
fail dword 0
sixty dword 0
seventy dword 0
eighty dword 0
ninety dword 0
hundred dword 0
index dword 0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMainl proc uses ebx edi esi, hWnd,wMsg,wParam,lParam
local @szBuffer[5]:byte
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
mov esi,[fail]
invoke SetDlgItemInt,hWnd,IDC_EDT2,esi,TRUE
mov esi,[sixty]
invoke SetDlgItemInt,hWnd,IDC_EDT3,esi,TRUE
mov esi,[seventy]
invoke SetDlgItemInt,hWnd,IDC_EDT4,esi,TRUE
mov esi,[eighty]
invoke SetDlgItemInt,hWnd,IDC_EDT5,esi,TRUE
mov esi,[ninety]
invoke SetDlgItemInt,hWnd,IDC_EDT6,esi,TRUE
mov esi,[hundred]
invoke SetDlgItemInt,hWnd,IDC_EDT7,esi,TRUE
.elseif eax == WM_COMMAND
.if ax == IDCANCEL
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMainl endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi, hWnd,wMsg,wParam,lParam
local @szBuffer[2]:byte
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDCANCEL
invoke EndDialog,hWnd,NULL
.elseif ax == IDC_BTN1;
invoke GetDlgItemInt,hWnd,IDC_EDT1,@szBuffer,TRUE
mov ebx ,index
mov score[ebx*(type score)],eax
inc index
inc ebx
mov index,ebx
mov ecx, lengthof score
mov eax,0
.elseif ax == IDOK
mov fail , 0
mov sixty, 0
mov seventy, 0
mov eighty, 0
mov ninety,0
mov hundred, 0
mov ecx,10
again: .if score[ebx*(type score)]<60
inc [fail]
.elseif score[ebx*(type score)]<70
inc [sixty]
.elseif score[ebx*(type score)]<80
inc [seventy]
.elseif score[ebx*(type score)]<90
inc [eighty]
.elseif score[ebx*(type score)]<100
inc [ninety]
.elseif score[ebx*(type score)]==100
inc [hundred]
.endif
inc ebx
loop again
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,offset _ProcDlgMainl,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_MFC2_DIALOG,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
四、 实验心得体会
(1) 本实验程序缺点
对细节方面处理不够好,例如让用户自定义ecx的大小不能在开始统计前直接在主界面先进行设定,点击录入后没有响应类似于MassageBox那样的提示或者Label提示录入成功,因为学艺不精,不知道如何使用汇编语言进行以上操作,望体谅。
(2) 本实验程序优点
能够适应不同人数的班级的成绩统计,不局限与一个界面的有限空间,ecx足够大时,能做到“无限”录入数据,而且界面简洁,减少空间。
(3) 开发心得体会
在刚拿到此课程设计任务的时候,对于刚接触汇编语言不久的我来说无疑是一个“艰巨”的任务,因为只学到了基础的知识且没有实际的汇编开发经验,所以心里莫名的慌。所以在进行开发之前,我在百度查阅来许多关于汇编的资料,还有类似的应用程序的资料,但我发现他们的共同点都是——局限于界面的控件数量的统计。因为之前是有一定的C++/C/JAVA的开发经验,所以思想上,对用户来说是十分的不便利的软件,因此就定下了我要做的软件的方向——“无限”录入数据。
但是,对于汇编语言基础学的不深的我来说,靠着C++/JAVA的思想是不够的,因为要实现相应的功能,则需要写出对应的汇编代码才能实现,因此花了很长时间通过各个渠道(如中国知网、万维网等)查阅资料及汇编语言的教程,最终才形成本次实验的我的应用程序。
虽然对于程序本身来说,它并不是完成品,只能算是一个半成品,但对于我来说,它就是我现有知识的完成品。对于应用程序的开发,并不是刚开发出来就是一个完美无瑕的程序,需要后继的不断改进,才能使程序更加的完整、更加的完美。
展开阅读全文