对输入的一些成绩进行分类汇总。
要求:
所有数字由键盘输入;
输入的成绩个数为任意个(至少 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