一、实验目的

掌握比较综合性的汇编程序设计流程,以及多分支情况下程序的设计技巧。

二、实验内容

设计程序统计学生数学成绩。分别归类90-99分、80-89分、70-79分、60-69分及60分以下,并将各段的人数及成绩存入对应的内存单元中,并在屏幕上显示。

三、程序清单

CRLF    MACRO
        MOV     DL,0DH
        MOV     AH,02H
        INT     21H
        MOV     DL,0AH
        MOV     AH,02H
        INT     21H
ENDM


DATA    SEGMENT                         ;数据段,成绩区
DATA1   DB      89H,92H,74H,85H,96H,73H,62H,78H
        DB      49H,59H,97H,66H,84H,81H,79H,67H
        DB      90H,88H,76H,82H,71H,69H,84H,81H
        DB      79H,65H,94H,86H,76H,82H,75H,83H
DA90    DB      16 DUP (0)              ;首字节为人数,随后为成绩
DA80    DB      16 DUP (0)
DA70    DB      16 DUP (0)
DA60    DB      16 DUP (0)
DA50    DB      16 DUP (0)
KKK     EQU     DA90 - DATA1            ;总人数
DATA    ENDS

CODE    SEGMENT
MAIN    PROC    FAR
        ASSUME  CS:CODE,DS:DATA,ES:DATA
START:  PUSH    DS
        SUB     AX,AX
        PUSH    AX
        MOV     AX,DATA
        MOV     DS,AX
        MOV     ES,AX
        LEA     SI,DATA1                ;SI 指向成绩表首
        MOV     CX,KKK                  ;循环数(总人数)送 CX
LOOP1:  MOV     AL,[SI]                 ;将成绩按字节送入AL
        CMP     AL,90H
        JNC     KK90                    ;成绩 >= 90 转
        CMP     AL,80H
        JNC     KK80                    ;成绩 >= 80 转
        CMP     AL,70H
        JNC     KK70                    ;成绩 >= 70 转
        CMP     AL,60H
        JNC     KK60                    ;成绩 >= 60 转
        LEA     DI,DA50                 ;不及格区首地址送 DI
        JMP     TTT
KK60:   LEA     DI,DA60                 ;60分区首地址送 DI
        JMP     TTT
KK70:   LEA     DI,DA70                 ;70分区首地址送 DI
        JMP     TTT
KK80:   LEA     DI,DA80                 ;80分区首地址送 DI
        JMP     TTT
KK90:   LEA     DI,DA90                 ;90分区首地址送 DI
TTT:    MOV     BL,[DI]                 ;BL = 存放人数地址
        INC     BL                      ;该段人数+1
        MOV     [DI],BL                 ;存该段人数
        MOV     AL,[SI]
        XOR     BH,BH
        MOV     [DI+BX],AL              ;成绩存入该段
        INC     SI                      ;修改地址指针
        LOOP    LOOP1
        LEA     SI,DA90
        CALL    DISPL                   ;显示 90 - 99分人数及成绩
        LEA     SI,DA80
        CALL    DISPL                   ;显示 80 - 89分人数及成绩
        LEA     SI,DA70
        CALL    DISPL                   ;显示 70 - 79分人数及成绩
        LEA     SI,DA60
        CALL    DISPL                   ;显示 60 - 69分人数及成绩
        LEA     SI,DA50
        CALL    DISPL                   ;显示 60分以下人数及成绩
        RET

DISPL   PROC    NEAR                    ;子程序:显示某段人数及成绩
        MOV     BL,[SI]                 ;取人数
        MOV     AL,BL
        MOV     CL,10
        CBW                             ;符号扩展指令,AL的内容扩展到AH,形成AX中的字。
        ;如果AL的最高有效位是0,则AH = 00,AL的最高有效位为1,则AH = FFH。AL不变。(即将AL的符号位移至AH)
        DIV     CL                      ;8位除法,被除数放在AX中,除数为8位在CL中,
        ;AL存储除法操作的商(即十位),AH存储除法操作的余数(即个位)
        MOV     DX,AX
        ADD     DL,30H                  ;将十位加30H转换为ASCII码,后面类似
        MOV     AH,02                   ;调用INT 21H中断的2号功能进行显示输出,输出字符存在DL中
        INT     21H                     ;显示十位
        MOV     DL,DH
        ADD     DL,30H
        MOV     AH,02
        INT     21H                     ;显示个位
        MOV     DL,20H                  ;空格的ASCII码
        MOV     AH,02
        INT     21H                     ;显示空格
DISP1:  INC     SI                      ;指向下一单元
        MOV     DL,20H
        MOV     AH,02
        INT     21H
        MOV     DL,[SI]                 ;取成绩
        MOV     CL,04
        ROL     DL,CL
        AND     DL,0FH
        ADD     DL,30H
        MOV     AH,02
        INT     21H                     ;显示十位
        MOV     DL,[SI]
        AND     DL,0FH
        ADD     DL,30H
        MOV     AH,02
        INT     21H                     ;显示个位
        DEC     BL
        JNZ     DISP1
        CRLF                            ;回车换行
        RET
DISPL   ENDP

MAIN    ENDP
CODE    ENDS
        END     START

四、实验过程

1.用编辑器建立源文件D101-4.ASM

2.用汇编程序MASM.EXE对源文件进行汇编,产生目标文件,再用连接程序LINK产生可执行文件

3.使用调试工具DEBUG进行程序调试 先用U命令反汇编,以便了解指令地址。显示结果如下,具体调试结果见第五部分。

五、实验结果分析

1.程序调试及结果 使用U命令查看汇编指令,可以看到共有32个成绩需要统计。

使用-d ds:0查看成绩内存区存放情况,使用-G 12指令执行到从成绩内存区读取成绩指令,可以看到第一个成绩为89,如下

使用-t指令单步运行程序,因为第一个成绩为89,所以在第一次比较时跳转不成立,在第二次比较时跳转成立,跳转到KK80标号处,如下

使用-g 51指令执行到将该成绩存入80分区内存地址段,再使用-d ds:0进行查看成绩区内存情况,可以看到此时80分区人数已经变为1,且此人成绩为89,如下

依次类推,将源地址指针SI进行加1,指向下一个成绩(字节),再进行循环操作,按照比较、跳转、取相应分区首地址、人数累加、存放成绩的流程进行操作,按照该流程循环成绩总数32次以后,成绩区内存如下

由上图可以看出,90分以上有5人,80-90分有0B(11)人,70-80分有9人,60~70分有5人,不及格成绩有2人,分别为49分和59分。

最后,再调用显示子程序DISPL对各分区人数及成绩进行打印,该子程序采用SI寄存器进行传参,参数为相应分区首地址,其内部核心思想为利用除法和调用INT 21H中断分别显示人数、成绩的十位和个位,如下。

至此,整个实验完成。

2.分析总结

首先,本次实验的重点在于掌握成绩的读取、判断分区、存放以及寄存器的调整,其中有个小技巧就是通过人数的增加刚好可以索引到当前成绩应该存放的位置,该小技巧的使用使得程序简洁明了,值得在今后的编程中借鉴。此外,本实验用到了变址寄存器寻址,应该对该部分加以理解。

类似文章