汇编实验课后题

DATA_SEG SEGMENT DATA
    ; 定义分数表,以字为单位
    SCORE_TABLE DW 65, 75, 80, 95, 70, 88, 92, 78, 63, 85
    ; 其他可能的分数...
    TOTAL_STUDENTS DW 10  ; 学生总数
DATA_SEG ENDS

CODE_SEG SEGMENT CODE
    ASSUME CS:CODE_SEG, DS:DATA_SEG

START:
    MOV AX, DATA_SEG ; 初始化数据段寄存器
    MOV DS, AX

    ; 调用 CNTMARKS 子程序统计各分数段人数
    ; 60-69
    MOV SI, OFFSET SCORE_TABLE ; 分数表的首地址
    MOV CX, TOTAL_STUDENTS    ; 学生总数
    MOV AL, 60                ; 最小值
    MOV AH, 69                ; 最大值
    CALL CNTMARKS             ; 调用子程序
    MOV DL, 0                ; 重置 DL 寄存器
    ; 此时 DL 包含了分数段 60-69 的人数

    ; 70-79
    MOV SI, OFFSET SCORE_TABLE ; 分数表的首地址
    MOV CX, TOTAL_STUDENTS    ; 学生总数
    MOV AL, 70                ; 最小值
    MOV AH, 79                ; 最大值
    CALL CNTMARKS             ; 调用子程序
    MOV DL, 0                ; 重置 DL 寄存器
    ; 此时 DL 包含了分数段 70-79 的人数

    ; 80-89
    MOV SI, OFFSET SCORE_TABLE ; 分数表的首地址
    MOV CX, TOTAL_STUDENTS    ; 学生总数
    MOV AL, 80                ; 最小值
    MOV AH, 89                ; 最大值
    CALL CNTMARKS             ; 调用子程序
    MOV DL, 0                ; 重置 DL 寄存器
    ; 此时 DL 包含了分数段 80-89 的人数

    ; 90-100
    MOV SI, OFFSET SCORE_TABLE ; 分数表的首地址
    MOV CX, TOTAL_STUDENTS    ; 学生总数
    MOV AL, 90                ; 最小值
    MOV AH, 100               ; 最大值
    CALL CNTMARKS             ; 调用子程序
    MOV DL, 0                ; 重置 DL 寄存器
    ; 此时 DL 包含了分数段 90-100 的人数

    ; 可以在这里输出结果或者进行其他操作

    ; 程序结束
    MOV AH, 4CH
    INT 21H

CODE_SEG ENDS
    END START
; CNTMARKS 子程序
; 功能:统计(AL,AH)分数段的人数。
; 入口参数:DS:SI 为需统计的分数表首地址,CX 中为总人数,AL 为要统计的分数段最小值,AH 为要统计的分数段最大值。
; 出口参数:DL,指定分数段(AL,AH)的人数

CNTMARKS PROC
    MOV CX, 0          ; 初始化计数器为0
    MOV DI, 0          ; 初始化索引为0

    ; 检查 SI 是否指向分数表的末尾
    NEXT_SCORE:
        CMP DI, CX      ; 比较索引与总人数
        JAE END_COUNT   ; 如果所有分数都已处理完,则跳到计数结束

        MOV AX, [SI]    ; 从分数表加载下一个分数到 AX
        CMP AL, AH      ; 比较最小值和最大值
        JA  INVALID_RANGE ; 如果最小值大于最大值,则跳到无效范围处理
        CMP AX, AL      ; 比较分数与最小值
        JB  NOT_IN_RANGE ; 如果分数低于最小值,则跳到不在范围内处理
        CMP AX, AH      ; 比较分数与最大值
        JA  NOT_IN_RANGE ; 如果分数高于最大值,则跳到不在范围内处理

        INC CX          ; 如果分数在指定范围内,增加计数器

    NOT_IN_RANGE:
        ADD SI, 2       ; 移到表中的下一个分数
        INC DI          ; 增加索引
        JMP NEXT_SCORE  ; 继续下一次迭代

    INVALID_RANGE:
        ; 处理最小值大于最大值的情况
        ; 在这里你可以设置DL为特定值或者根据需要处理错误
        MOV DL, 0FFH    ; 设置DL为一个特殊值,表示错误
        JMP END_COUNT   ; 跳到计数结束

    END_COUNT:
        MOV DL, CX      ; 将计数值移动到DL寄存器,用于输出
        RET
CNTMARKS ENDP

你可能感兴趣的:(汇编)