汇编语言成绩汇总

汇编语言成绩汇总

题目要求:

对输入的一些成绩进行分类汇总。

要求:

  1. 所有数字由键盘输入;

  2. 输入的成绩个数为任意个(至少 10 个);

  3. 对成绩进行归类并输出显示在屏幕:

  • 显示最高成绩、最低成绩、平均成绩(平均成绩保留一位小数)

  • 显示 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 
posted on 2021-10-28 01:58  QSun  阅读(474)  评论(0编辑  收藏  举报