文章目录
一.作业要求
采用汇编程序实现如下功能:生成一个班的成绩数据(60人,0~100),对成绩进行分类汇总得到不及格学生比例(<60),中比例([60,75]),良比例([75,90]),优比例(>=90)。
二.思路
三.要点
1.产生随机数
利用时间服务读取时钟计数器的值,产生随机数
RAND PROC
PUSH CX
PUSH DX
PUSH AX
STI ; IF置1,允许响应可屏蔽中断
MOV AH, 0 ; 读时钟计数器值,CX:DX=时钟计数值
INT 1AH ; 调用BIOS中断
MOV BX, DX ; 随机数存BX
POP AX
POP DX
POP CX
RET
RAND ENDP
2.控制随机数的范围在[0, 100]
[0, 100]之间有101个整数,可以采用除以101然后求余数的方法,将数据转为[0, 100]中的随机数。
这里要用到无符号数除法指令 DIV 源操作数
注意:
- 指令中使用16位除以8位,32位除以16位的格式。
- 被除数、除数都不能为立即寻址。
- 被除数放在AX / DX:AX中,在指令中隐含。
- 16位运算的商放在AL中,余数放在AH中,32位运算的商放在AX中,余数放在DX中。
......
; 将随机数控制在[0, 100]之间
START:
MOV AX, DATA
MOV DS, AX ; 初始化DS
MOV CX, 60 ; 60个学生
LEA SI, RANDOM ; 获取RANDOM单元偏移地址
LEA DI, SCORE ; 获取SCORE单元偏移地址
XOR AX, AX ; 清零
XOR DX, DX ; 清零
LP:
MOV AL, [SI] ; 取数据
MOV DL, 65H ; 除以101,控制区间
DIV DL ; 无符号数相除,余数放在AX
MOV SCORE[DI], AH ; 将数据存入
NEXT:
INC SI ; 指针移动
INC DI ; 指针移动
XOR AX, AX ; 清零
LOOP LP
......
3.用分支结构实现成绩分类
将生成的成绩先与90做比较,判断是否为优;
如果结果小于90,与75比较,判断是否为良;
如果结果小于75,与60比较,判断是否为中;
这里要用到的指令:
(1)比较指令 CMP 目的操作数,源操作数
注意:
- 该指令执行“目标操作数 - 源操作数”,不产生运算结果,仅影响标志。
比如对于无符号操作数 AX 和 BX 来说, CMP AX, BX ,若 AX > BX,则标志位 CF = 0;若 AX < BX,则标志位 CF = 1;若 AX = BX,则标志位 CF = 1,ZF = 1。 - 指令的目的操作数不能是立即寻址;
- 目的操作数和源操作数不能同时为存储器操作数。
(2)条件转移指令 JC/JNC
指令 | 条件 |
---|---|
JC | CF = 1 |
JNC | CF = 0 |
4.存储成绩分类结果
将成绩分类结果分别存在 YOU、LIANG、ZHONG 和 BUJIGE 中,将计数结果存储在 YOU_COUNT、LINAG_COUNT、ZHONG_COUNT 和 BUJIGE_COUNT 中。
四.完整汇编代码
;
;*****************************************************************************
; @file score.asm
; @author Xiaoxiao
; @date 2020-9-25
; @brief 统计60个学生成绩,得到不及格学生比例(<60),中比例([60,75)),良比例([75,90)),优比例(>=90)
; @blog https://blog.csdn.net/weixin_43470383/article/details/108625957
;*****************************************************************************
;
data segment
; 随机、优秀、良好、中等、不及格的成绩
RANDOM DB 60 DUP(0)
YOU DW 60 DUP(0)
LIANG DW 60 DUP(0)
ZHONG DW 60 DUP(0)
BUJIGE DW 60 DUP(0)
; 随机、优秀、良好、中等、不及格的个数
COUNT DW 0
YOU_COUNT DW 0
LIANG_COUNT DW 0
ZHONG_COUNT DW 0
BUJIGE_COUNT DW 0
ends
code segment
ASSUME DS:DATA CS:CODE
START:
MOV AX, DATA
MOV DS, AX
MOV CX, 60 ; 60个学生
JUDGE_0:
CALL RAND ; 产生随机数,保存在 BL 中
MOV SI, COUNT
INC COUNT
SHL SI, 1
MOV RANDOM[SI], BL
CMP RANDOM[SI], 90 ; 判断是否为优
JC JUDGE_1 ; 若成绩小于90,跳转
YOU_SCORE:
MOV SI, YOU_COUNT
INC YOU_COUNT ; 成绩为优的个数加一
SHL SI, 1
MOV YOU[SI], BX
LOOP JUDGE_0
JMP $
JUDGE_1:
CMP RANDOM[SI], 75 ; 判断是否为良
JC JUDGE_2 ; 若成绩小于75,跳转
LIANG_SCORE:
MOV SI, LIANG_COUNT
INC LIANG_COUNT ; 成绩为良的个数加一
SHL SI, 1
MOV LIANG[SI], BX
LOOP JUDGE_0
JMP $
JUDGE_2:
CMP RANDOM[SI], 60 ; 判断是否为良
JC BUJIGE_SCORE ; 若成绩小于60,跳转
ZHONG_SCORE:
MOV SI, ZHONG_COUNT
INC ZHONG_COUNT ; 成绩为中的个数加一
SHL SI, 1
MOV ZHONG[SI], BX
LOOP JUDGE_0
JMP $
BUJIGE_SCORE:
MOV SI, BUJIGE_COUNT
INC BUJIGE_COUNT ; 成绩为不及格的个数加一
SHL SI, 1
MOV BUJIGE[SI], BX
LOOP JUDGE_0
JMP $
RAND PROC
PUSH CX
PUSH DX
PUSH AX
STI ; IF置1,允许响应可屏蔽中断
MOV AH, 0 ; 读时钟计数器值,CX:DX=时钟计数值
INT 1AH ; 调用BIOS中断
MOV AX, DX ; 清高6位
AND AH, 3
MOV DL, 101
DIV DL ; 除101,产生0~100余数
MOV BL, AH ; 余数存BX,作随机数
POP AX
POP DX
POP CX
RET
RAND ENDP
CODE ENDS
END START