汇编结构体实现学生成绩管理
关于思维导图:初学汇编,在老师发布本次实验任务时,自己并没有思路,也不知道该如何具体完成本次实验,于是先根据老师给的实验要求做了一张思维导图,当然流程图最初也只是有老师给出的任务的一个大体框架,最终的这张思维导图也是在边完成实验功能边完善的。
- 实验完成的具体功能为:
①用户输入1,录入学生基本信息并输出(当用户选择不再录入信息时,将本次已录入的所有学生的基本信息打印出)输出完成后,返回菜单,继续等待用户输入想要完成的功能;
②用户输入2,将已录入的学生信息按照成绩由大到小排序并输出最终排名完成的结果,最后返回菜单,继续等待用户输入想要完成的功能;
③用户输入3,按照学号查找学生信息并输出,若未查找到,询问用户是否继续查找并等待用户输入,若用户选择再次查找则继续查找,用户选择不再查找则返回菜单继续等待用户选择功能;若查找到,则输出该学生的基本信息,并询问用户用否将该学生的信息进行修改,若用户选择修改,则调用修改子程序;若不修改,则返回菜单继续等待用户选择功能;
④用户输入4,退出该程序;
⑤用户输入其他字符,输出输入错误,并提示用户先添加学生信息。
先放上运行结果图运行结果图
菜单
选择1号功能
选择2号功能
选择3号功能
选择4号功能
输入其他字符
汇编实现学生成绩管理,这当然是老师布置的期末大作业了。虽然难度不大,而且实验并没有太鲜明的亮点,但这是本人第一次写blog来记录自己完成的作业,希望大家多多提意见,或者关于功能实现方法可以互相交流。
下面讲解的只是各功能的部分关键代码,想要源码的亲们,欢迎大家加我vx呀~~~vx:_Aurora_smile
(ps:不是免费的哈,源码66.66💰 添加时备注来意哈:汇编代码)
- 定义结构体用于存放学生信息
STUDENT STRUC ;;STUDENT为结构名
NAMES DB 20 DUP (?)
NUMBER DB 20 DUP (?)
SCORE DW ?
STUDENT ENDS
STU1 STUDENT X DUP(<>) ;;结构预置(在数据段中),用于在程序中直接引用,X自己定义个数在输入学生成绩时,只要个数不超过X就可以选择是否继续输入。
- 宏定义:在数据段之前进行了定义
宏名字 MACRO [哑元1,哑元2,...]
语句串(宏体)
ENDM
①OUTZIFU: 2号功能输出回车换行
②INPUT: 1号功能输入字符
③OUTPUT: 2号功能输出字符
④OUTCHUAN:9号功能输出串
⑤SHUJU:数字转换,用于对学生成绩的数据处理
SHUJU MACRO A,B ;;A为要处理的数据,B为除数
MOV SI,A ;;在程序中,要处理的数据为学生的成绩
MOV AX,SI
MOV DX,0
DIV B ;;处理一个成绩,进行了3次宏调用,第一次输出百位,第二次
MOV A,DX 输出十位,第三次输出各位
MOV DL,AL
ADD DL,30H
MOV AH,2
INT 21H
ENDM
⑥利用宏显示菜单
4. **六个子程序:**
子程序名 PROC 属性
…
子程序名 ENDP
→(1)Add_information:录入学生基本信息(学生学号、学生姓名、学生成绩)
①判断输入的学号是否合法(学号为数字,如果是回车代表本次学号输入完毕):
.IF AL==13 正确输入:(回车后会提示用户输入姓名)
JMP INPUT_NUM
.ELSEIF AL>='0' && AL<='9'
MOV STU1[BX].NUMBER[DI],AL
INC DI
.ELSE 错误输入:(提示输入错误,等待用户再次输入)
OUTZIFU
OUTCHUAN ERROR1
MOV AL,0
JMP SHURU
.ENDIF
②判断输入的姓名是否合法 (学号为az或AZ如果是回车代表本次姓名输入完毕):
.IF AL==13
JMP INPUT_NAME
.ELSEIF AL>='A' && AL<='Z' || AL>='a' && AL<='z'
MOV STU1[BX].NAMES[DI],AL
INC DI
.ELSE
OUTZIFU
OUTCHUAN ERROR1
OUTZIFU
MOV AL,0
JMP INPUT_N
.ENDIF
③判断输入的成绩是否合法(成绩必须由数字构成且在0~100之间,如果是回车代表本次成绩输入完毕):
判断输入是否合法:
```c
.IF AL==13
JE OVER
.ELSEIF AL>='0' && AL<='9'
SUB AL,30H
CBW
XCHG AX,CX
MUL DL
ADD CX,AX
.ELSE 错误输入:(提示必须为0~100)
JMP SCOREERROR
.ENDIF
JMP INPUTSCORE
判断是否在0~100之间:
只需要比较是否大于100就可以,因
为若是负数再输入负号时就会判断不合法。
对输入的成绩的处理:
一个字符一个字符地输入将这个字符减去30h,使其变成‘0’~‘9’之间的数字,进行字扩展后,将AX与CX内的数值进行交换(输入的数在AL中即此时在AX中,先前将CX清零),给AX乘10(此处DL先前赋值为10作为乘数),再将AX与CX相加。
关键代码:
SUB AL,30H
CBW
XCHG AX,CX
MUL DL
ADD CX,AX
运算过程举例:比如想要如数一个两位数,第一次输入的是9,第二次输入的是8
该代码完成的功能就是(((0*10)+9)*10)+8,从而得到98。
→(2)PAI_XU:对学生信息按照成绩由大到小排序
流程图:
本实验采用冒泡排序法:比较相邻两名同学的成绩,如果前者小于后者则将两名同学的信息进行交换。每外循环一次,就将最小的学生的成绩移到最后面,内循环是相邻成绩之间的比较。
关键代码:
MOV BX,0 ;;若学生人数大于等于2,则开始对成绩进行比较排序
MOV SI,COUNT
DEC SI
MOV COUNT2,SI ;;COUNT2控制外循环,COUNT3控制内循环
WAIXUNHUAN: ;;外循环,内循环比较完一次所有学生的成绩,开始下一次外循环
MOV SI,COUNT2
MOV COUNT3,SI
MOV BX,0
NEIXUNHUAN: ;;内循环,输入时的相邻学生成绩之间的比较
MOV AX,STU1[BX].SCORE
ADD BX,42
CMP AX,STU1[BX].SCORE
JB EXCHANGE
DEC COUNT3
.IF COUNT3>0
JMP NEIXUNHUAN
.ENDIF
DEC COUNT2
.IF COUNT2>0
JMP WAIXUNHUAN
.ENDIF ;;内循环和外循环都全部结束
JMP OVER3
→(3)CHA_ZHAO:按照学号查找学生信息
在数据段定义了INBUF存储单元,存放用户输入的想要查找学号,输入完毕后,与结构体中存放的学号依次比较。若找到用户输入的学号,则输出该学生的基本信息;若未查找到,则显示没有改信息,询问用户是否再次查找,若用户选择是,则继续进行查找;若用户选择否,则返回到菜单。
关键代码:用到了串比较,首先在代码段加载附加数据段:
LEA SI,INBUF
LEA DI,STU1[BX].NUMBER
MOV CX,20
REPE CMPSB ;;重复比较串,直到CX=CX-1=0或者发现两个串不等时退出
→(4)XIU_GAI:修改学生信息
将查找的学号的学生信息直接进行修改,相当于继续填写学生信息,把之前的信息进行覆盖。
修改完之后重新进行排序。此处代码不进行列举。
→(5)Basic_information:输出学生基本信息
关键代码:
OUTCHUAN STU1[BX].NUMBER ;;输出学号
OUTCHUAN STU1[BX].NAMES ;;输出姓名
MOV CX,STU1[BX].SCORE
SHUJU CX,BAI ;;输出百位成绩 宏定义SHUJU:对学生成绩的数字转换
SHUJU CX,SHI ;;输出十位成绩
SHUJU CX,YI ;;输出个位成绩
ADD BX,42
DEC COUNT1
.IF COUNT1==0
JMP OVER2 ;;临时存储学生人数为0时,就代表全部输出完毕
.ELSEIF COUNT1>0 ;;临时存储学生人数大于0,继续进行输出
JMP SHUCHU
.ENDIF
→(6)Rank_information:输出排名后的学生信息
输出带排名的信息是在排序后完成的,将学生信息排完序,学生信息将按照成绩由大到小在存储单元存放,因此,只在输出基本信息的基本上再输出排名即可。RANKS为名次,在此之前RANKS赋值为0,需要先自加1,再跟随基本信息依次输出排名。
关键代码:
INC RANKS
OUTCHUAN KONGGE
MOV DL,RANKS
ADD DL,30H
OUTPUT DL
PS:欢迎大家多多留言提出问题,本次大作业由于期末时间紧张,会有部分BUG可能没被发现,大家多多指出呀~~~