汇编语言——学生成绩管理系统

实现学号,姓名,成绩输入,排序输出

1.菜单显示

1)在缓冲区定义了菜单所显示的内容(直到读到"$"为止),命名MENU,并做美化处理

 MENU DB 13,10
    	DB '~~~~~~~~~~~~~~~~~MENU~~~~~~~~~~~~~~~~~~',13,10
    	DB '|         1.INPUT                     |',13,10
    	DB '|         2.OUTPUT(RANK)              |',13,10
    	DB '|         0.QUIT                      |',13,10
    	DB '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~',13,10
        DB 'PLEASE INPUT YOUR CHOICE:$'

2)菜单显示使用子程序调用,并使用while伪指令保证在功能运行完成后,能使菜单再次出现,持续循环

MENU PROC;菜单子程序
	MOV AX,3  ;清屏
    INT 10H
    S_SHUCHU MENU;显示菜单
    RET
MENU ENDP
.WHILE 1;死循环
	CALL MENU ;调用菜单
	CALL CHOICE ;选择功能
	.ENDW	

2.功能选择

1)启用菜单输入提示,内容定义在缓冲区,并做输入合法性判断,非法输入会有错误提示,并按任意键返回菜单重新选择功能

3.输入

1)对所需输入的内容进行对应标题提示,先输入学号,其次姓名,最后成绩

2)输入功能使用子程序调用——INPUT PROC NEAR

3)输入时所有结束方式均为空格

4)由于学号位数不定,所以结束学号输入后不确定如何间隔能准确定位到姓名提示的下方,所以使用INT 10H中的2号功能,使光标对齐输入时对应的项,界面整齐

        MOV AH,2  ;置光标位置
		MOV BH,0  ;页号
		MOV DX,SI
		MOV DH,7;行
		ADD DH,DL 
		MOV DL,16;列
		INT 10H   ;使光标对齐在name

5)由于成绩的特殊性,输入成绩时单独调用成绩输入子程序GR_SHURU PROC,输入时会将数据存入CX,每次会判断CX中的数是否大于100,大于则提示错错误

GR_SHURU PROC
 	MOV CX,0
 	MOV DL,10
	.WHILE CX<=100
		SHURU			;键盘接收一个字符
		CHECK AL			;检测输入的是否为数字
	.IF AL == ' '
		MOV [BX+DI],CL		;如果输入空格,则成绩接收结束,并存入对应储存单元
		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

4.排序

使用冒泡排序法,进行内外循环,我们需要对成绩进行排序,所以数据从第13位开始取即可,先取第一行的数据给DL,再取第二行的数据给DH再将第二行的数据和第一行的数据相比,如果前一个数据小于后一个,则开始把两个数组内的所有数据XCHG。比较完第一个和第二个后,跳到下一行,比较第二行和第三行,比较N-1次,比较完最后两个数据时,最小的成绩就在结构体数组的最后一个了,然后外循环把CX减1,重回到结构体的第一行,因为最小值已经在上次循环中找出,所以此次内循环需要比较的次数N-2次,找出第二小的成绩,以此类推直到内外循环均结束,冒泡排序完成,为降序

5.输出

1)输出使用的也是子程序,先把结构体数组的首地址给BX,使用SI是否小于N判断是否继续输出下一行,其中学号和姓名因为已经定义好了对应空间,所以只需改变CX使之循环对应次数遍历每一个字节即可

2)成绩的输出比较特殊所以单独调用成绩输出的宏定义,接收成绩mov给AL,防止AH中有东西,所以要先把AH清零,把CL赋10作为除数,使用多位输出的套路,把存成绩的AL除10,并把余数AH赋给DL压入栈内,如果商AL不为0则一直循环此操作,最后从低到高把每一位都压入栈内,然后再出栈输出即可

3)因为是排序完再输出的,所以输出的即为排序好的数据,所以输出每一行数据时同时输出当前行数作为名次,即可完成排名的显示

6.运行效果

 

程序代码如下:

;学生成绩管理系统,实现输出和排序输出两个功能,使用冒泡排序,
;各项输入均以“空格”结束
;项目时间:2021.11.27
;合作小组成员:夏佳怡、张庆伟、王伟、赵启凯、李佳瑶、闫家栋
students STRUCT			 ;定义结构体
	ID DB 9 DUP(?)  	 
	NAME1 DB 3 DUP(?)	 
	GRADE DB ?			 
students ENDS   ;结构体共13个字节
 
DATAS SEGMENT
	N = 3			;数组大小定义
    MEMBER students N DUP(<>)  ;定义结构体数组
    MENU DB 13,10
    	DB '~~~~~~~~~~~~~~~~~MENU~~~~~~~~~~~~~~~~~~',13,10
    	DB '|         1.INPUT                     |',13,10
    	DB '|         2.OUTPUT(RANK)              |',13,10
    	DB '|         0.QUIT                      |',13,10
    	DB '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~',13,10
    	DB 'PLEASE INPUT YOUR CHOICE:$'
    WARNING DB '	INPUT ERROR!!!$'
    SHURUTIP db 13,10, "Each item ends with a space","$"
   	NEXT db 13,10,13, 10,"Press any key to return to the menu",13,10,"$"
    HINT1 DB 13,10,'ID(9)		NAME(3)		GRADE(0-100)',13,10,'$'
    HINT2 DB 13,10,'ID(9)		NAME(3)		GRADE(0-100)	RANK',13,10,'$'
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!=' '
		SHUCHU 13
		SHUCHU 10
		S_SHUCHU WARNING	
		S_SHUCHU NEXT		;提示输入错误
		SHURU					;让提示显示,阻止直接清屏,按任意键返回主菜单
		CALL MAIN				;跳回主菜单
	.ENDIF
ENDM
 
;成绩输出宏定义
GR_SHUCHU MACRO X
	MOV AL,X        ;接收成绩给AL
	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
 
;主程序代码段
CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS
START:
    MOV AX,DATAS
    MOV DS,AX
MAIN PROC FAR    
	.WHILE 1	;死循环
	CALL SHOW   ;调用菜单
	CALL CHOICE ;选择功能
	.ENDW		
MAIN ENDP 
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 WARNING		;成绩输入不合格输出警告
	RET
GR_SHURU ENDP
    
;菜单显示子程序
SHOW PROC NEAR
	MOV AX,3  ;清屏
    INT 10H
    S_SHUCHU MENU
    RET
SHOW ENDP
;菜单选项子程序
CHOICE PROC NEAR
	SHURU		;调用宏输入一个字符
	.IF AL==31H		 ;调用输入功能
		CALL INPUT
	.ELSEIF AL ==32H	;调用输出功能,且排序
		CALL RANK		;调用排序,对数据按成绩进行排序,由高到低
		CALL OUTPUT
	.ELSEIF AL==30H 	;退出程序	
		JMP EXIT
	.ELSE
		S_SHUCHU WARNING		;输出警告提示
	.ENDIF
	S_SHUCHU NEXT
	SHURU	;接收一个字符,用于暂停当前界面,按任意键刷新菜单
	RET
CHOICE ENDP
 
;输入子程序
INPUT PROC NEAR
	S_SHUCHU SHURUTIP
	S_SHUCHU HINT1
	
	LEA BX,MEMBER		;结构体初始化指针,行定位
	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,3		;姓名输入,最大可输入4个字符
		MOV DI,9		;结构体定义的NAME段位置定位
	LPI1:
		SHURU
		.IF AL == ' '	
			JMP XMI		;输入空格表示输入下一项
		.ELSE
			MOV [BX+DI],AL  ;对应位置存入相应字符,最多输入4位
			INC DI
		.ENDIF
		LOOP LPI1
	XMI:
		SHUCHU '	'
		SHUCHU '	'
		MOV DI,12		;定位到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,MEMBER
	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,3
	LPO1:
		MOV DL,[BX+DI]
		SHUCHU DL
		INC DI
		LOOP LPO1
		
		SHUCHU '	'
		SHUCHU '	'
		MOV DL,[BX+DI]
		GR_SHUCHU DL
		
		ADD BX,TYPE students
		INC SI
		
		SHUCHU '	'
		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,MEMBER	;回到结构体的第一行
	.WHILE CX
		MOV DI,12
		MOV DL,[BX+DI]		;取到的第一个值,与它的后一位值比较,对应到结构体为GRADE部分
		MOV DH,[BX+DI+13]	;取到的第二个值,与其前一位比较,同上
			.IF DL<DH		;如果前一个小于后一个成绩,则进行数据交换
			MOV DI,0
				.WHILE DI<13				;结构体实际长度为13
					XCHG AL,[BX+DI]
					XCHG [BX+DI+13],AL		;数据交换
					XCHG [BX+DI],AL
					INC DI
				.ENDW
			.ENDIF
		ADD BX,TYPE students	;跳到第二个位置与后一段数据比较
		DEC CX					;内循环自减
	.ENDW
	POP CX
	DEC CX						;外循环自减
.ENDW
	RET
RANK ENDP
;结束
 
CODES ENDS
    END START

参考:学生成绩管理系统(汇编)_咚の窝-CSDN博客_汇编学生成绩管理系统

  • 13
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏佳怡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值