实验具体内容

  1. 编写一个汇编程序,实现字符串的复制功能,并且将复制的字符串显示出来。(选做部分:倒序显示复制字符串)
  2. 利用中断调用,在屏幕上显示1—9之间随机数。中断号86H。
  3. 键盘输入10个学生的成绩,编写一个程序统计60 - 69分,70 - 79分,80 - 89分,90 - 99分及100分的人数,分别存放在Score6,Score7,Score8,Score9和Score10单元中。输出10个学生的成绩如下:65 98 78 82 88 95 72 62 90 100

1. 字符串复制显示

(1)流程图

正序输出:

img

倒序输出:

img

(2)汇编源代码

正序输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
DATAS SEGMENT
string_a db 'The School of Information Science and Engineering Shandong University','$'
COUNT DW $-OFFSET STRING_A;计算string_a的长度,$为当前地址
DATAS ENDS

EXT SEGMENT
string_b db 100 dup(?);定义一个段用来接收复制的字符串
EXT ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,ES:EXT
START:
MOV AX,DATAS
MOV DS,AX;将源数据块段地址赋给DS
MOV AX,EXT
MOV ES,AX;将缓存区的段地址赋给ES

MOV SI,OFFSET STRING_A;将源数据块偏移地址赋给SI
MOVDI,OFFSET STRING_B;将缓存区偏移地址赋给DI
MOV CX,COUNT;为后面的loop循环做准备
CLD;将标志寄存器Flag的方向标志位DF清零

GOON:
LODSB;把DS:SI指向的存储单元中的数据装入AL,然后根据DF标志增减SI
STOSB;把AL中的数据装入ES:DI指向的存储单元,然后根据DF标志增减DI
LOOP GOON

OUTPUT:
MOV AX,EXT
MOV DS,AX
MOV DX,OFFSET STRING_B
MOV AH,09
INT 21H;显示输出经复制的字符串

MOV AH,4CH
INT 21H
CODES ENDS
END START

倒序输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
DATAS SEGMENT
string_a db 10,13,'The School of Information Science and Engineering Shandong University','$'
COUNT dw $-OFFSET STRING_A;计算string_a的长度,$为当前地址
TXT1 db 'The original string:','$',10,13
TXT2 db 10,13,'The inverted string:','$'
cr db 10,13,'$';换行
DATAS ENDS
STACKS SEGMENT
db 128 dup(?)
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV BX,OFFSET STRING_A;将源数据字符串偏移地址传送给BX
MOV CX,COUNT;将字符串的长度传送给CX

ORIGIN:
LEA DX,txt1
mov ah,09h
int 21h;输出显示提示信息

LEA DX,STRING_A
MOV AH,09H
INT 21H;输出显示正序的字符串,与下面输出的倒序做对比


SOUT:
LEA DX,TXT2
MOV AH,09H
INT 21H;输出显示提示信息

PUSH CX;将CX中的数据入栈备份
DEC CX
DEC CX;这里将cx减2,为了下面loop循环正确调整bx的指向
DOWN:
INC BX;调整bx指向字符串最后一个字符
LOOP DOWN

POPCX;使原来原来备份的数据出栈,这里也可以不用栈段,再进行一次mov
DEC CX;为了下面输出显示的次数和字符串长度相同

lea dx,cr
mov ah,09h
int 21h;换行
UP:
MOV DL,[BX]
MOV AH,02
INT 21H;从字符串最后一个字符开始逆序输出
DEC BX
LOOP UP

MOV AH,4CH
INT 21H;程序结束
CODES ENDS
END START

(3)实验代码、过程、相应结果(截图)并对实验进行说明和分析

正序输出:

img

倒序输出:

img

这里还可以考虑用入栈、出栈的方式来实现逆序输出显示。

2. 中断产生随机数

(1)流程图

img

(2)汇编源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
DATAS SEGMENT
TXT1 DB 13,10,'The random number: ','$';提示生成随机数
DATAS ENDS

STACKS SEGMENT
DB 128 DUP(?)
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS

RDNUM PROC NEAR
PUSH CX
PUSH DX
MOV AH,0
INT 1AH;读取当前时钟值,CX:DX=时钟计数值
MOV AX,DX
MOV DX,0
MOV BX,10
DIV BX;商存放在AX中,余数存放在DX中
ADD DL,30H;将DL中的数值转换为对应的ASCII码
MOV AH,02H;输出显示DL的数据
INT 21H
POP DX
POP CX
IRET ;中断返回
RDNUM ENDP

START:
MOV AX,DATAS
MOV DS,AX

LEA DX,TXT1
MOV AH,09H
INT 21H;输出显示随机数产生提示信息

MOV AX,0
MOV DS,AX;使段地址DS指向0000

MOV BX,86H*4;将86号中断的地址赋给BX

MOV WORD PTR DS:[BX],OFFSET RDNUM
MOV WORD PTR DS:[BX+2],SEG OFFSET RDNUM;修改中断向量表,使86号中断的地址指向RDNUM子程序

INT 86H;调用86号中断,即调用RDNUM子程序

MOV AH,4CH
INT 21H;程序结束
CODES ENDS
END START

(3)实验代码、过程、相应结果(截图)并对实验进行说明和分析

第一次生成随机数:

img

第二次生成随机数:

img

第三次生成随机数:

img

3. 统计成绩段人数

(1)流程图

img

(2)汇编源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
DATAS SEGMENT
TXT1 DB 'Please input score(only 60 to 100): ','$'
SCORE6 DB 13,10,'The number of score are 60 to 69: ','$'
SCORE7 DB 13,10,'The number of score are 70 to 79: ','$'
SCORE8 DB 13,10,'The number of score are 80 to 89: ','$'
SCORE9 DB 13,10,'The number of score are 90 to 99: ','$'
SCORE10 DB 13,10,'The number of score is 100: ','$'
OUTSCORE DB 13,10,'The number of outscore: ','$'
SCORE_6 DB 30H
SCORE_7 DB 30H
SCORE_8 DB 30H
SCORE_9 DB 30H
SCORE_10 DB 30H
SCORE_OUT DB 30H;用于存储相应分数段的数量,全部初始化数量为0
SPACE DB 32,32,'$';双空格
DATAS ENDS

STACKS SEGMENT
DB 128 DUP(?)
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS

CMP_ PROC NEAR;定义CMP_子程序
CMP AL,31H;和'1'比较
JZ CMP10;相等则跳转到CMP10标号

CMP AL,36H;和'6'比较
JZ CMP6;相等则跳转到CMP10标号

CMP AL,37H;和'7'比较
JZ CMP7;相等则跳转到CMP10标号

CMP AL,38H;和'8'比较
JZ CMP8;相等则跳转到CMP10标号

CMP AL,39H;和'9'比较
JZ CMP9;相等则跳转到CMP10标号

JMP CMPOUT;如果都不等于,则首数字为其他,跳转到CMPOUT标号
CMP10:
ADD [SCORE_10],1;如果首数字为1,则[SCORE_10]加1
JMP EXIT

CMP6:
ADD [SCORE_6],1;如果首数字为1,则[SCORE_6]加1
JMP EXIT

CMP7:
ADD [SCORE_7],1;如果首数字为1,则[SCORE_7]加1
JMP EXIT

CMP8:
ADD [SCORE_8],1;如果首数字为1,则[SCORE_8]加1
JMP EXIT

CMP9:
ADD [SCORE_9],1;如果首数字为1,则[SCORE_9]加1
JMP EXIT

CMPOUT:
ADD [SCORE_OUT],1;;如果首数字为其他,则[SCORE_OUT]加1
JMP EXIT

EXIT:
LEA DX,SPACE
MOV AH,9
INT 21H;输出显示两个空格
RET;返回主程序

CMP_ ENDP


START:
MOV AX,DATAS
MOV DS,AX
LEA DX,TXT1
MOV AH,9
INT 21H
MOV CX,10;设置输入次数

INPUT:
MOV AH,1
INT 21H;输入分数最高位
CALL CMP_
LOOP INPUT;循环继续输入分数的最高位数,直到输完10个数为止

OUTPUT:
LEA DX,SCORE6
MOV AH,9
INT 21H;输出显示提示信息
MOV AL,[SCORE_6]
MOV DL,AL
MOV AH,2
INT 21H;输出首数字为6的个数

LEA DX,SCORE7
MOV AH,9
INT 21H;输出显示提示信息
MOV AL,[SCORE_7]
MOV DL,AL
MOV AH,2
INT 21H;输出首数字为7的个数

LEA DX,SCORE8
MOV AH,9
INT 21H;输出显示提示信息
MOV AL,[SCORE_8]
MOV DL,AL
MOV AH,2
INT 21H;输出首数字为8的个数

LEA DX,SCORE9
MOV AH,9
INT 21H;输出显示提示信息
MOV AL,[SCORE_9]
MOV DL,AL
MOV AH,2
INT 21H;输出首数字为9的个数

LEA DX,SCORE10
MOV AH,9
INT 21H;输出显示提示信息
MOV AL,[SCORE_10]
MOV DL,AL
MOV AH,2
INT 21H;输出首数字为1的个数

LEA DX,OUTSCORE
MOV AH,9
INT 21H;输出显示提示信息
MOV AL,[SCORE_OUT]
MOV DL,AL
MOV AH,2
INT 21H;输出首数字为其他的个数

MOV AH,4CH
INT 21H;程序结束
CODES ENDS
END START

(3)实验代码、过程、相应结果(截图)并对实验进行说明和分析

img

目前仅支持60~100的分数统计,其实还可以通过多个cmp指令进行比较,位数确定等来进行程序升级,达到统计0 - 100分的效果。