(汇编语言)实验七 简单的学生成绩管理系统

一. 实验目的

  1. 掌握综合的分析和解决问题的能力。
  2. 对预习报告中的源代码进行上机实现,记录实验结果。

二. 实验内容

1.内容:
自主选择一个较复杂的要解决的实际问题,编程实现。
用汇编语言写一个简单的学生成绩管理系统。

2.要求:
1)综合利用所学,自己设计并完成一个较为负责的实际问题,写出学生同一门课程的成绩的录入、排序与修改。
2)对预习报告中的源代码进行上机实现,记录实验结果。

三. 实验过程和程序

(1)程序代码:

students STRUCT			 ;偏移量
	SNO DB 9 DUP(?)  	 ;0-8
	NAME1 DB 4 DUP(?)	 ;9-12
	GRADE DB ?			 ;13
students ENDS   ;结构体共14个字节
 
DATAS SEGMENT
	N = 5			;数组大小定义
    STU_ARRAY students N DUP(<>)  ;结构体数组
    JIANGE DD 10 DUP (?)  ;数据溢出显示遮挡菜单
    LIST DB 13,10
    	DB '*~*~*~*~*~*~*~LIST*~*~*~*~*~*~*~*~*~*~*',13,10
    	DB '@         1.INPUT                     @',13,10
    	DB '@         2.OUTPUT(RANK)              @',13,10
    	DB '@         3.FIND(SNO)                 @',13,10
    	DB '@         0.QUIT                      @',13,10
    	DB '*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*',13,10
    	DB 'PLEASE INPUT YOUR CHOICE:$'
    WARING DB 'INPUT ERROR!!!$'
    HINT1 DB 13,10,'SNO		NAME	GRADE',13,10,'$'
    HINT2 DB 13,10,'SNO		NAME	GRADE	RANK',13,10,'$'
    HINT3 DB 13,10,'INPUT ERROR! PLEASE AFRESH.',13,10,'$'
    HINT4 DB ' OLD GRADE:$'
    HINT5 DB 13,10,'ARE THE SCORES MODIFIED?(y/n)',13,10,'$'
    FIND DB 13,10,'PLEASE ENTER THE (SNO) YOU WANT TO FIND,END BY SPACE:',13,10,'$'
    NFIND DB 13,10,'NOT FOUND!!',13,10,'$'
    RESULT DB 13,10,'PLEASE ENTER NEW GRADE:',13,10,'$'
    SOURCE DB 9 DUP(?)
DATAS ENDS
 
;字符输出宏定义
SHUCHU MACRO X
	MOV AH,2
	MOV DL,X
	INT 21H
ENDM
 
;字符串输出宏定义
S_SHUCHU MACRO Y
	LEA DX,Y
	MOV AH,9
	INT 21H
ENDM
 
;单字符输入宏定义
SHURU MACRO
	MOV AH,1
	INT 21H
ENDM
 
;字符检测
CHECK MACRO X
	.IF X>'9' || X<'0' && X!=' '
		S_SHUCHU HINT3			;提示输入错误
		SHURU					;让提示显示,避免被刷掉,按任意键返回主菜单
		JMP RESTORE				;跳回主菜单
	.ENDIF
 
ENDM
 
;成绩输出宏定义
GR_SHUCHU MACRO X
	MOV AL,X        ;接收成绩
	MOV AH,0		;AX高位清0
	MOV CL,10		;除数,等会用来取余数和商
	MOV DH,0		;压栈前高位置0
	.WHILE AL != 0  ;如果商不为0,则继续除10
		DIV CL
		MOV DL,AH	;余数置于DL
		ADD DL,30H  ;转换为ASCII码
		PUSH DX		;压栈
		INC DH
	MOV AH,0		;高位即余数清0
	.ENDW
	;循环完成取数操作,即从右到左,从个位数开始取数,一直到最高位停止取数
	.IF DH == 0				;判断输入成绩是否为0,若为0直接输出
		SHUCHU 30H
	.ELSE					;否则弹出栈中相应内容输出
			MOV CL,DH
		.WHILE CL
			POP DX
			SHUCHU DL
			DEC CL
		.ENDW
	.ENDIF			;成绩输出结束
ENDM
 
	;主程序代码段         MAIN
CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV AX,TYPE STUDENTS
    
RESTORE:			;输入错误后,跳回的点
	.WHILE 1
	CALL SHOW   ;调用菜单
	CALL CHOICE ;接收选项并调用对应子程序
	.ENDW		;死循环
 
EXIT:    
	MOV AH,4CH
    INT 21H
	;主程序代码段结尾		MAIN	
 
;成绩输入子程序
GR_SHURU PROC
 	MOV CX,0
 	MOV DL,10
	.WHILE CX<=100
		SHURU			;键盘接收一个字符
		CHECK AL			;检测输入的是否为数字
	.IF AL == ' '
		MOV [BX+DI],CL		;如果输入空格,则成绩接收结束,并存入对应储存单元,即结构体GRADE单元
		RET
	.ELSE
		SUB AL,30H		;进行ASCII码转换为数字
		CBW				;AL扩展为AX,高位清0
		XCHG CX,AX		;交换数值
		MUL DL			;AL×10放入AX中
		ADD CX,AX		;将数字相加,得到新的数值,放入cl中
	.ENDIF
	.ENDW
	S_SHUCHU WARING		;成绩输入不合格输出警告
	RET
GR_SHURU ENDP
    
;菜单显示子程序
SHOW PROC NEAR
	MOV AX,3  ;清屏
    INT 10H
    S_SHUCHU LIST
    RET
SHOW ENDP
 
;菜单选项子程序
CHOICE PROC NEAR
	SHURU		;调用宏输入一个字符
	.IF AL=='1'		 ;调用输入功能
		CALL INPUT
	.ELSEIF AL =='2'	;调用输出功能,且排序
		CALL RANK		;调用排序,对数据按成绩进行排序,由高到低
		CALL OUTPUT
	.ELSEIF AL=='3'		;调用查找功能
		CALL SEARCH
	.ELSEIF AL=='0'		;退出程序	
		JMP EXIT
	.ELSE
		S_SHUCHU WARING		;输出警告提示
	.ENDIF
	SHURU	;接收一个字符,用于暂停当前界面,按任意键刷新菜单
	RET
CHOICE ENDP
 
;输入子程序
INPUT PROC NEAR
	S_SHUCHU HINT1
	
	LEA BX,STU_ARRAY		;结构体初始化指针,行定位
	MOV SI,0				;统计输入的行数
	
	.WHILE SI<N				;N为行数,控制输入几行
		MOV CX,9			;循环,学号共定义9个字节空间
		MOV DI,0			;相对指针,用于定位对应的结构体内的元素,列定位
	LPI:
		SHURU
		CHECK AL		;检测输入字符是否为数字
		.IF AL == ' '
			JMP XHI			;若输入空格,则跳到下一项输入
		.ELSE
			MOV [BX+DI],AL 	;将学号逐个输入到对应的位置,最大9位
			INC DI
		.ENDIF
		LOOP LPI
	XHI:
		SHUCHU '	'
		PUSH BX    ;光标对齐
		MOV AH,2
		MOV BH,0
		MOV DX,SI
		MOV DH,9
		ADD DH,DL
		MOV DL,16
		INT 10H   ;使光标对齐在name
		POP BX
		
		MOV CX,4		;姓名输入,最大可输入4个字符
		MOV DI,9		;结构体定义的NAME段位置定位
	LPI1:
		SHURU
		.IF AL == ' '	
			JMP XMI		;输入空格表示输入下一项
		.ELSE
			MOV [BX+DI],AL  ;对应位置存入相应字符,最多输入4位
			INC DI
		.ENDIF
		LOOP LPI1
	XMI:
		SHUCHU '	'
		MOV DI,13		;定位到GRADE区域,成绩输入
		CALL GR_SHURU		;调用子程序,成绩输入
		
		ADD BX,TYPE students	;跳到下一行,即结构体数字的下一行,加上相应的结构体大小
		INC SI				;行数统计自增一次
		SHUCHU 13
		SHUCHU 10
	.ENDW	
	RET
INPUT ENDP
 
 
;输出子程序
OUTPUT PROC NEAR	;该部分可参照输入子程序,理解地址所对应数据,方便理解代码
	S_SHUCHU HINT2
	
	LEA BX,STU_ARRAY
	MOV SI,0
	
	.WHILE SI<N
		MOV CX,9
		MOV DI,0
	LPO:
		MOV DL,[BX+DI]
		SHUCHU DL
		INC DI
		LOOP LPO
		
		SHUCHU '	'
		MOV CX,4
	LPO1:
		MOV DL,[BX+DI]
		SHUCHU DL
		INC DI
		LOOP LPO1
		
		SHUCHU '	'
		MOV DL,[BX+DI]
		GR_SHUCHU DL
		
		ADD BX,TYPE students
		INC SI
		
		SHUCHU '	'
		MOV DX,SI		;获取当前的行数
		GR_SHUCHU DL	;将行数转换为对应的ASCII码,输出对应的行数
		
		SHUCHU 13
		SHUCHU 10
	.ENDW
	RET	
OUTPUT ENDP
 
;降序排序
RANK PROC NEAR
	MOV CX,N-1			;总的数据个数减一,即循环次数
.WHILE CX				;冒泡排序法
	PUSH CX				;外循环次数保护,压栈
	LEA BX,STU_ARRAY	;回到结构体的第一行
	.WHILE CX
		MOV DI,13
		MOV DL,[BX+DI]		;取到的第一个值,与它的后一位值比较,对应到结构体为GRADE部分
		MOV DH,[BX+DI+14]	;取到的第二个值,与其前一位比较,同上
			.IF DL<DH		;如果前一个小于后一个成绩,则进行数据交换
			MOV DI,0
				.WHILE DI<14				;结构体实际长度为14
					XCHG AL,[BX+DI]
					XCHG [BX+DI+14],AL		;.while内为前后数据交换部分
					XCHG [BX+DI],AL
					INC DI
				.ENDW
			.ENDIF
		ADD BX,TYPE students	;跳到第二个位置与后一段数据比较,冒泡排序法
		DEC CX					;内循环自减
	.ENDW
	POP CX
	DEC CX						;外循环自减
.ENDW
	RET
RANK ENDP
 
;查找并修改子程序
SEARCH PROC NEAR
	S_SHUCHU FIND
	
	LEA BX,STU_ARRAY	;取存储数据的首地址,即结构体首地址
	LEA BP,SOURCE		;存放查找的学号的首地址
	
	MOV CX,9			;循环,学号共定义了9个字节空间
	MOV DI,0			;相对指针,用于定位需要存入元素,列定位
LPF:
	SHURU
	CHECK AL		;检测输入字符是否为数字
	.IF AL == ' '
		JMP FNXT			;若输入空格,则跳到下一项输入
	.ELSE
		MOV [BP+DI],AL 	;将学号逐个输入到对应的位置,最大9位
		INC DI
	.ENDIF
	LOOP LPF
FNXT:
	MOV CX,N		;查找对比的个数,即总共的行数(学生数)
LPF1:
	PUSH CX			;保护外循环次数,压栈
		MOV CX,9	;学号一共有9个存储区域
		MOV DI,0
	LPF2:					
		MOV AL,[BX+DI]		;结构体,已经存入的数据
		MOV AH,[BP+DI]		;查找输入的学号
		CMP AL,AH			;按位对比学号
		JNZ FNXT1			;如果有一个没有相等则跳过该学生,该学生不是要查找的学生
		INC DI
		.IF DI == 9
			POP CX			;弹出多余的CX,避免无法返回,即RET执行和栈有关,需先弹出栈中多余的数据,避免程序运行出错
			JMP FNXT2		;如果查找到对应学号则跳出,执行修改成绩程序段
		.ENDIF
	LOOP LPF2				;循环9次对比完一位的学号
		FNXT1:
		ADD BX,TYPE students	;指向下一个学生,即下一行数据区域
		POP CX				;外循环被保护的CX,出栈
LOOP LPF1					;一共对比N次,即和N个学生的学号比较
	S_SHUCHU NFIND	
	RET
FNXT2:
	S_SHUCHU HINT4
	MOV SI,13				;指针指向GRADE对应段
	MOV DL,[BX+SI]			;get到原始成绩
	GR_SHUCHU DL			;输出旧的成绩
	S_SHUCHU HINT5			;提示是否修改成绩
	SHURU					;接收字符,判断是否修改成绩
	.IF AL=='y'
		S_SHUCHU RESULT
		MOV DI,13
		CALL GR_SHURU			;调用输入成绩子程序
	.ENDIF
	RET
SEARCH ENDP
;结束
 
CODES ENDS
    END START



结果如下:
1、输入五个学生的成绩:
在这里插入图片描述
2、对学生的成绩进行排序:
在这里插入图片描述
3、修改其中一个学生的成绩:
在这里插入图片描述
4、重新排序:
在这里插入图片描述
5、退出程序:
在这里插入图片描述

  • 11
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值