一.题目要求
用汇编语言编写完整的程序,实现一个简单的成绩管理系统,班级人数用宏定义确定。
[1]显示菜单,按键1~5执行相应功能。
[2]选项1,输入学生学号和成绩。
[3]选项2,根据学生学号查询成绩。
[4]选项3,将学生成绩排序显示。
[5]选项4,统计平均成绩,0-59,60-79,80-89,90~100的学生人数。
[6]选项5,程序结束,返回操作系统。
[7]完成程序编辑、调试和运行。
[8]提交完整的源程序和运行结果截图
二.代码展示
DATA SEGMENT
SHOW DB 'Please enter a number(1-5) to chose FUNCTION ',0DH,0AH,
'-----------------------------------------',0DH,0AH,
'| FUNCTION1:INPUT ID(0000) AND GRADE(00)|',0DH,0AH,
'| FUNCTION2:ENTER ID TO INQUIRE GRADE |',0DH,0AH,
'| FUNCTION3:GRADE SORTING |',0DH,0AH,
'| FUNCTION4:AVERAGE GRADE |',0DH,0AH,
'| FUNCTION5:QUIT |',0DH,0AH,
'-----------------------------------------',0DH,0AH,'$'
SHOWS DB 'PLEASE ENTER YOUR CHOICE:','$'
FUN DW FUNCTION1,FUNCTION2,FUNCTION3,FUNCTION4,FUNCTION5
COUNT DW 0;用于存学生数
COUNT1 DW 4,2,1
COUNT2 DW 10
COUNT3 DW 0,0,0,0,'$';用于保存功能4中的计数
ID DW 100 DUP(?);存学号
GRADE DW 100 DUP(?);存成绩
SHOW11 DB ' 0-59:','$'
SHOW12 DB ' 60-79:','$'
SHOW13 DB ' 80-89:','$'
SHOW14 DB '90-100:','$';功能4显示
SHOW2 DB ' ID GRADE',0DH,0AH,'$'
SHOW21 DB ' ID:','$'
SHOW22 DB 'GRAND:','$';功能2显示
SHOW3 DB 'PLEASE ENTER THE NUMBER OF STUDENT',0DH,0AH,'$'
SHOW4 DB ' ','$'
SHOW5 DB 'THE ID IS WRONG',0DH,0AH,'$'
SHOW6 DB 'AVRTAGE GRADE:','$'
DIVISORS DW 1000, 100, 10, 1
RESULTS DB 0,0,0,0,'$';存放结果
CUN DW 10,10
DATA ENDS
STACK SEGMENT STACK'stack'
DW 100H DUP(?)
TOP LABEL WORD
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
OUT_DX MACRO Y;输出字符串
LEA DX,Y
MOV AH,9H
INT 21H
ENDM
CHANGE_LINE MACRO;换行
MOV AH,02H
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
ENDM
NUMBER MACRO;输入学生数
OUT_DX SHOW3;显示提示
CALL INPUT
LEA SI,COUNT
MOV WORD PTR [SI],BX;将学生数目存入COUNT
ENDM
START:
MOV AX,DATA
MOV DS,AX
NUMBER
CALL MENU
START1:
OUT_DX SHOWS
MOV AH,01H
INT 21H;输入选项(1-5)
SUB AL,30H
CMP AL,0
JB START1
CMP AL,5
JA START1;输入非1-5,程序重新运行
DEC AL
SHL AL,1
XOR AH,AH
MOV BX,AX
CHANGE_LINE
CALL FUN[BX];调用各个功能程序
JMP START1
MOV AH,4CH
INT 21H
MENU PROC NEAR
CHANGE_LINE
OUT_DX SHOW;显示菜单
RET
MENU ENDP
FUNCTION1 PROC NEAR;选项1,输入学生学号和成绩
OUT_DX SHOW2;显示表头
LEA SI,COUNT
MOV CX,WORD PTR [SI]
LEA SI,ID
LEA DI,GRADE
ONE:
CALL INPUT1
MOV WORD PTR [SI],BX;将学号存入ID
ADD SI,2
OUT_DX SHOW4
CALL INPUT2
MOV WORD PTR [DI],BX;将成绩存入GRADE
ADD DI,2
CHANGE_LINE
LOOP ONE
RET
FUNCTION1 ENDP
FUNCTION2 PROC NEAR;选项2,根据学生学号查询成绩
OUT_DX SHOW21
CALL INPUT1;输入学号
CHANGE_LINE
LEA SI,COUNT
MOV CX,WORD PTR [SI]
LEA SI,ID
LEA DI,GRADE
TWO:
CMP WORD PTR [SI],BX
JZ QUIT;ID中的学号与输入学号相等时,跳转输出成绩
ADD SI,2
ADD DI,2
LOOP TWO
OUT_DX SHOW5
JMP QUIT1;ID中没有输入学号时提示错误,并退出选项
QUIT:
OUT_DX SHOW22
MOV AX,WORD PTR [DI]
CALL OUTPUT;输出成绩
CHANGE_LINE
QUIT1:
RET
FUNCTION2 ENDP
FUNCTION3 PROC NEAR;选项3,将学生成绩排序显示
LEA SI,COUNT
MOV CX,WORD PTR [SI]
LEA SI,ID
LEA DI,GRADE
DEC CX
MOV AX,CX
MUL COUNT1[2]
ADD DI,AX
ADD SI,AX
RP1:
PUSH CX
PUSH SI
PUSH DI
RP2:
MOV BX,WORD PTR [DI]
CMP BX,WORD PTR [DI-2]
JAE EXCHANGE;后一位大于前一位,跳转下一次比较
XCHG BX,WORD PTR [DI-2]
MOV WORD PTR [DI],BX;后一位小于前一位,成绩互相交换位置
MOV BX,WORD PTR [SI]
XCHG BX,WORD PTR [SI-2]
MOV WORD PTR [SI],BX;后一位小于前一位,学号互相交换位置
EXCHANGE:
SUB SI,2
SUB DI,2
LOOP RP2
POP DI
POP SI
POP CX
LOOP RP1;冒泡排序法,有小到大排序
OUT_DX SHOW2;显示表头
LEA SI,COUNT
MOV CX,WORD PTR [SI]
MOV COUNT1[4],CX
LEA SI,ID
LEA DI,GRADE
MOV CUN[0],DI
THREE:
MOV AX,WORD PTR [SI]
ADD SI,2
PUSH SI
CALL OUTPUT;输出排序后的学号
OUT_DX SHOW4
MOV DI,CUN[0]
MOV AX,WORD PTR [DI]
ADD DI,2
PUSH DI
CALL OUTPUT;输出排序后的成绩
CHANGE_LINE
POP DI
POP SI
MOV CUN[0],DI
DEC COUNT1[4]
CMP COUNT1[4],0
JA THREE
RET
FUNCTION3 ENDP
FUNCTION4 PROC NEAR;选项4,统计平均成绩,
;0~59,60~79,80~89,90~100的学生人数
OUT_DX SHOW6;显示表头
LEA SI,COUNT
MOV CX,WORD PTR [SI]
MOV COUNT1[4],CX
LEA DI,GRADE
PUSH DI
DEC CX
MOV AX,WORD PTR [DI]
FOUR:
ADD DI,2
ADD AX,WORD PTR [DI];求成绩累加和,存入AX
LOOP FOUR
XOR DX,DX
DIV COUNT1[4]
CALL OUTPUT;输出平均值
CHANGE_LINE
POP DI
FIVE:
CMP WORD PTR [DI],60
JB L1
CMP WORD PTR [DI],80
JB L2
CMP WORD PTR [DI],90
JB L3
INC COUNT3[6];计算成绩在90-100的学生数
JMP OVER
L1:
INC COUNT3[0];计算成绩在0-59的学生数
JMP OVER
L2:
INC COUNT3[2];计算成绩在60-79的学生数
JMP OVER
L3:
INC COUNT3[4];计算成绩在80-89的学生数
JMP OVER
OVER:
ADD DI,2
DEC COUNT1[4]
CMP COUNT1[4],0
JA FIVE
OUT_DX SHOW11
MOV AX,COUNT3[0]
CALL OUTPUT;输出成绩在0-59的学生数
CHANGE_LINE
OUT_DX SHOW12
MOV AX,COUNT3[2]
CALL OUTPUT;输出成绩在60-79的学生数
CHANGE_LINE
OUT_DX SHOW13
MOV AX,COUNT3[4]
CALL OUTPUT;输出成绩在80-89的学生数
CHANGE_LINE
OUT_DX SHOW14
MOV AX,COUNT3[6]
CALL OUTPUT;输出成绩在90-100的学生数
CHANGE_LINE
RET
FUNCTION4 ENDP
FUNCTION5 PROC NEAR;选项5,程序结束,返回操作系统
MOV AH,4CH
INT 21H
RET
FUNCTION5 ENDP
INPUT PROC NEAR;输入任意位
MOV BX,0
NUM:
MOV AH,1;输入一位字符至AL
INT 21H
SUB AL,30H;将输入数字的ASCII码转换为十进制数字
JL EXIT
CMP AL,9
JG EXIT;输入非数字退出
CBW
XCHG AX,BX
MUL COUNT2[0]
XCHG AX,BX
ADD BX,AX
JMP NUM;输入为数字时跳至NUM继续输入
EXIT:
RET
INPUT ENDP
INPUT1 PROC NEAR;输入4位
MOV BX,0
PUSH COUNT1[0]
NUM1:
MOV AH,1;输入一位字符至AL
INT 21H
SUB AL,30H;将输入数字的ASCII码转换为十进制数字
JL EXIT1
CMP AL,9
JG EXIT1;输入非数字退出
CBW
XCHG AX,BX
MUL COUNT2[0]
XCHG AX,BX
ADD BX,AX
DEC COUNT1[0]
CMP COUNT1[0],0
JA NUM1;输入为数字时跳至NUM继续输入
EXIT1:
POP COUNT1[0]
RET
INPUT1 ENDP
INPUT2 PROC NEAR;输入2位
MOV BX,0
PUSH COUNT1[2]
NUM2:
MOV AH,1;输入一位字符至AL
INT 21H
SUB AL,30H;将输入数字的ASCII码转换为十进制数字
JL EXIT2
CMP AL,9
JG EXIT2;输入非数字退出
CBW
XCHG AX,BX
MUL COUNT2[0]
XCHG AX,BX
ADD BX,AX
DEC COUNT1[2]
CMP COUNT1[2],0
JA NUM2;输入为数字时跳至NUM继续输入
EXIT2:
POP COUNT1[2]
RET
INPUT2 ENDP
OUTPUT PROC NEAR;输出程序
MOV SI, OFFSET DIVISORS
MOV DI, OFFSET RESULTS
MOV CX,4
CAL:
MOV DX,0
DIV WORD PTR [SI];AX除1000,AX为商,DX为余数
ADD AL,30H;将数字转换为ASCII码
MOV BYTE PTR [DI],AL;将运算结果从高位到低位依次存入results
INC DI
ADD SI,2
MOV AX,DX;将余数DX附给AX
LOOP CAL
MOV CX,3;循环4次,如果前四位均为0,则将第五位输出
MOV DI, OFFSET RESULTS
NZ:
CMP BYTE PTR [DI],'0'
JNE PRINT;结果大为0时跳入输出程序print
INC DI
LOOP NZ
PRINT:
MOV DX,DI
MOV AH,9
INT 21H
RET
OUTPUT ENDP
CODE ENDS
END START
三.结果展示