汇编语言成绩汇总
汇编语言成绩汇总
题目要求:
对输入的一些成绩进行分类汇总。
要求:
-
所有数字由键盘输入;
-
输入的成绩个数为任意个(至少 10 个);
-
对成绩进行归类并输出显示在屏幕:
-
显示最高成绩、最低成绩、平均成绩(平均成绩保留一位小数)
-
显示 90-100 分人数,80-89 分人数,70-79 分人数,60-69 分人数,低于 60 分人数,
-
显示无效数字个数(非数字或大于 100 数字个数)
代码:
;-----数据段------
DATAS SEGMENT
STR1 DB 'PLEASE INPUT SCORES',0AH,0DH,'$'
STR2 DB 0AH,0DH,'THE HIGHEST SCORE IS:','$'
STR3 DB 0AH,0DH,'THE LOWEST SCORE IS:','$'
STR4 DB 0AH,0DH,'AVERAGE SCORE IS:','$'
STR5 DB 0AH,0DH,'THE NUMBER OF ERROR SCORE:','$'
STR6 DB 0AH,0DH,'THE NUMBER OF CORRET SCORE:','$'
STR7 DB 0AH,0DH,'THE NUMBER OF 90--100;','$'
STR8 DB 0AH,0DH,'THE NUMBER OF 80--90:','$'
STR9 DB 0AH,0DH,'THE NUMBER OF 70--80:','$'
STR10 DB 0AH,0DH,'THE NUMBER OF 60-70:','$'
STR11 DB 0AH,0DH,'THE NUMBER OF <60:','$'
STR12 DB 0AH,0DH,'THE SUM OF SCORES:','$'
SCORES DW 256 DUP(0);输入的成绩数组
STAS DW 20 DUP(0);各个统计量
DATAS ENDS
;-----堆栈段-------
STACKS SEGMENT
DW 256 DUP(0)
STACKS ENDS
;-----代码段-------
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV DX,OFFSET STR1;输出提示1
MOV AH,09H
INT 21H
;---输入数据---
MOV CX,0FFH;将计数器CX设为一个大数,在循环内部进行循环的跳出
MOV SI,0
INPUTS:
CALL INPUT
ADD SI,2;偏移地址指向下一个
LOOP INPUTS
;---计算各统计量---
STATS:
MOV SI,0
CALL STAT
;---打印最大值---
PRINT_MAX:
MOV DX,OFFSET STR2;输出提示2
MOV AH,09H
INT 21H
MOV SI,0
CALL PRINT
;---打印最小值---
PRINT_MIN:
MOV DX,OFFSET STR3;输出提示3
MOV AH,09H
INT 21H
MOV SI,2
CALL PRINT
;---打印错误输入个数---
PRINT_ERR:
MOV DX,OFFSET STR5;输出提示5
MOV AH,09H
INT 21H
MOV SI,16
CALL PRINT
;---打印数组长度,即正确输入个数---
PRINT_LEN:
MOV DX,OFFSET STR6;输出提示6
MOV AH,09H
INT 21H
MOV SI,18
CALL PRINT
;---打印90-100成绩个数---
PRINT_S9:
MOV DX,OFFSET STR7;输出提示7
MOV AH,09H
INT 21H
MOV SI,6
CALL PRINT
;---打印80-89成绩个数---
PRINT_S8:
MOV DX,OFFSET STR8;输出提示8
MOV AH,09H
INT 21H
MOV SI,8
CALL PRINT
;---打印70-79成绩个数---
PRINT_S7:
MOV DX,OFFSET STR9;输出提示9
MOV AH,09H
INT 21H
MOV SI,10
CALL PRINT
;---打印60-69成绩个数---
PRINT_S6:
MOV DX,OFFSET STR10;输出提示10
MOV AH,09H
INT 21H
MOV SI,12
CALL PRINT
;---打印<60的成绩个数---
PRINT_S5:
MOV DX,OFFSET STR11;输出提示11
MOV AH,09H
INT 21H
MOV SI,14
CALL PRINT
;---打印成绩和---
PRINT_SUM:
MOV DX,OFFSET STR12;输出提示12
MOV AH,09H
INT 21H
MOV SI,4
CALL PRINT
;---打印平均数,且保留一位小数---
PRINT_AVG:
PRINT_1:
MOV DX,OFFSET STR4;输出提示4
MOV AH,09H
INT 21H
CALL AVERAGE
MOV SI,4
CALL PRINT;打印整数位
;---平均数小数计算----
AVG_FLOAT:
;---计算第一位小数---
MOV AX,DX
MOV CX,10
MUL CX
MOV CX,STAS[18];数组长度
MOV DX,0
DIV CX
MOV STAS[4],AX;第一位小数存入STAS[4]
;---继续四舍五入得第二位小数---
MOV AX,DX
MOV CX,10
MUL CX
MOV CX,STAS[18];数组长度
MOV DX,0
DIV CX
CMP AX,5;第二位小数和5比较
JB PRINT_2
INC STAS[4];第二位小数大于5,则第一位小数加一
PRINT_2:
MOV DL,'.';打印小数点
MOV AH,02H
INT 21H
PRINT_3:
MOV SI,4;打印小数位
CALL PRINT
EXIT:
MOV AH,4CH
INT 21H
;-----------主程序段结束------------
;-----------子程序段------------
;-----------输入子程序-------------
INPUT PROC NEAR
PUSH AX;保护除CX外的寄存器,因为CX是循环计数器所以不能入栈
PUSH BX
PUSH DX
MOV BX,0
CLC
INLP:
MOV AH,01H
INT 21H
CMP AL,20H;和空格比较,是就跳到SAVE
JE SAVE
CMP AL,0DH;和回车比较,是就跳到OVER
JE OVER
;---错误字符处理,0<AL<9---
CMP AL,30H
JL ERR
SUB AL,30H
CMP AL,9
JG ERR;出现错误后进行处理
;---正常字符操作---
MOV AH,0;AH置零,便于数据储存
XCHG AX,BX;BX中存有输入成绩的上一位,将其存于AX,并将输入成绩的当前为存于BX
MOV DX,10
MUL DX;将AX中数据,即成绩的上一位乘以10
ADD BX,AX;将两位加起来并存入BX,等待下次操作
JMP INLP
SAVE:
CMP BX,64H;和100比较
JA SAVE_ERR;大于100则跳到错误保存
MOV SCORES[SI],BX;输入成绩存入数组
INC STAS[18];数组长度+1
POP DX
POP BX
POP AX
RET
SAVE_ERR:
MOV AX,STAS[16];错误数据数+1
INC AX
MOV STAS[16],AX
SUB SI,2
POP DX
POP BX
POP AX
RET
OVER:
MOV CX,1;计数器记为1,本次输入数据保存后退出循环
JMP SAVE;保存最后输入的数据
OVER_ERR:
MOV CX,1
JMP SAVE_ERR
ERR:
MOV AH,01H;等待下个输入
INT 21
CMP AL,20H;空格就跳到错误保存
JE SAVE_ERR
CMP AL,0DH;回车就调到错误结束
JE OVER_ERR
JMP ERR;否则即继续等待下个输入
RET
INPUT ENDP
;---------统计子程序----------
STAT PROC NEAR
PUSH DX
PUSH CX
PUSH BX
PUSH AX
MOV CX,STAS[18];数组长度
ADD CX,CX
MOV AX,SCORES[SI]
MOV BX,0;最小成绩0
MOV DX,64H;最大成绩,16进制的100
COMP:
MOV AX,SCORES[SI]
CMP AX,5AH;和90比较
JG S90
CMP AX,50H;和80比较
JG S80
CMP AX,45H;和70比较
JG S70
CMP AX,3CH;和60比较
JG S60
JMP S59
S90:
INC STAS[6];90-100
JMP SUM
S80:
INC STAS[8];80-90
JMP SUM
S70:
INC STAS[10];70-80
JMP SUM
S60:
INC STAS[12];60-70
JMP SUM
S59:
INC STAS[14];<60
JMP SUM
SUM:
ADD STAS[4],AX;求和,存入STAS[4]
;-----找最大值,暂存于BX----
MAX:
CMP BX,SCORES[SI];小于BX,就跳过,大于BX,就更新BX
JNB MIN
MOV BX,SCORES[SI]
;-----找最大值,暂存于DX----
MIN:
CMP DX,SCORES[SI];大于DX,就跳过,小于BX,就更新BX
JNA NEWDATA
MOV DX,SCORES[SI]
NEWDATA:
ADD SI,2
CMP SI,CX;判断是否循环完了整个数组
JB COMP
MOV STAS[0],BX;最大值存入STA[0]
MOV STAS[2],DX;最小值存入STA[2]
POP AX
POP BX
POP CX
POP DX
RET
STAT ENDP
;-------打印子程序-----
PRINT PROC NEAR
PUSH DX
PUSH CX
PUSH BX
PUSH AX
;------每次打印一位字符------
MOV CX,0;记录入栈次数
MOV AX,STAS[SI];每次要打印的内容存入AX中
MOV BX,10
PUS:
;-----低位先入栈,高位后入栈
MOV DX,0
DIV BX ;除以10
PUSH DX;将余数入栈
INC CX;记录入栈次数作为输出时的循环次数
CMP AX,0
JNZ PUS;当商为0时退出循环
POS:
;-----高位先输出,低位后输出
POP DX
ADD DX,30H
MOV AH,2
INT 21H
LOOP POS
POP AX
POP BX
POP CX
POP DX
RET
PRINT ENDP
;-------平均数子程序------
AVERAGE PROC NEAR
PUSH AX
PUSH BX
MOV DX,0
MOV AX,STAS[4];将SUM给AX
MOV BX,STAS[18];将数组长度给BX
DIV BX
MOV STAS[4],AX;将商存在原SUM的位置
POP BX
POP AX
RET
AVERAGE ENDP
CODES ENDS
END START