目录

实验任务

  1. 课本实验7 寻址方式在数据化数据访问中的应用

解答:

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
assume cs:code
data segment
;1B
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985'
db '1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
;4B
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980
dd 590827,803530,1183000,1843000,2758000,3753000,4649000,5937000
;2B
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends
stack segment
dw 0,0,0,0,0,0,0
stack ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
;总体思路,分两个循环来进行,第一个循环是将数据段中的年份,收入复制到table段中,
;第二个循环是复制雇员数并计算出人均收入,然后再将结果复制到table段中
code segment
start:
mov ax,data
mov es,ax
mov si,0
mov ax,table
mov ds,ax
mov di,0
mov ax,stack
mov ss,ax
mov sp,16
mov bx,0
mov cx,21
;es 表示数据段的内容,ds表示table段的内容,
s0:
mov ax,es:[si]
mov ds:[di+bx],ax
add si,2
add di,2
mov ax,es:[si]
mov ds:[di+bx],ax
mov ax,es:[si+82]
mov ds:[bx+di+3],ax
mov ax,es:[si+84]
mov ds:[bx+di+5],ax
add si,2
mov di,0
add bx,16 ;将偏移地址变成下一行
loop s0
mov bx,0
mov si,168 ;雇员数的偏移地址
mov di,5 ;收入的偏移地址
mov cx,21
s1:
mov ax,es:[si]
mov ds:[bx+di+5],ax
mov ax,ds:[bx+di]
mov dx,ds:[bx+di+2]
div word ptr ds:[bx+di+5]
mov ds:[bx+di+8],ax
add si,2
add bx,16
loop s1
mov ax,4c00h
int 21h
code ends
end start

程序运行前的table段:

程序运行后的table段:

  1. 数据段的第一个串为学生本人的姓名拼音小写,转变为大写字母后存入它后面的数据区。例如

DATA SEGEMENT

NAME1 DB ‘liweihua’

NAME2 DB 8 DUP (0)

DATA ENDS

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
assume cs:code, ds:data, ss:stack
data segment
name1 db 'liweihua'
name2 db 8 dup (0)
data ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start:
mov ax,data ;初始化栈段和数据段
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,10h
mov si,offset name1
mov bx,offset name2
sub bx,si ;name1 - name2 得到name1长度
mov cx,bx ;循环name1的长度次数
s: mov al,[si] ;将 ds:si 复制到al
and al,11011111B ;与运算,将小写转变为大写
mov [bx+si],al ;存到name2处数据段
inc si ;si自增,指向下一个字母
loop s
mov ax,4c00h
int 21H
code ends
end start

程序运行前结果:

程序运行后结果:

  1. 定义下面的4行4列矩阵数组,要求将上三角的所有元素累加,结果存入SUM。

X1 DB 10,20,30,40

DB 20,30,40,50

DB 30,40,50,60

DB 40,50,60,70

SUM DW 0

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
assume cs:codesg,ds:data
DATA segment
DB 10,20,30,40
DB 20,30,40,50
DB 30,40,50,60
DB 40,50,60,70
SUM DW 0
DATA ENDS
codesg segment
START:
MOV ax,DATA
MOV ds,ax ;将DS指向DATA段
mov ax,0
mov bx,0
mov dx,0
mov di,4 ;矩阵有4列
mov cx,4 ;矩阵有4行,外循环为4次
s: push cx ;将CX入栈
mov si,0 ;SI表示列
mov cx,di ;内循环每次少加一个数(列),每次少循环一次
s0: mov dl,ds:[bx+si] ;将矩阵上三角每行从第一个数放入DL中
add ax,dx ;AX=AX+DX,将数字相加后放入AX中
inc si ;进行下一列的操作
loop s0
sub di,1 ;内循环每次少加一个数(列),每次少循环一次
add bx,5 ;指向矩阵上三角每行第一个数
pop cx ;将CX出栈
loop s
mov [SUM],ax ;将相加的结果存入SUM中
MOV AH,4CH
INT 21H
CODESG ENDS
END START

程序运行前:

程序运行后:

这个结果与手算的结果相一致,因此程序运行正确

  1. 杨辉三角

创建一个10行16列的字节数组,并按照杨辉三角的数学规律给数组赋值。杨辉三角形状如下:

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

1 5 10 10 5 1

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
assume cs:code, ss:stack, ds:data
data segment
;声明一段10行16列首列数字为1的二维数组
array db 10 dup( 1, 15 dup(0) )
data ends
stack segment
dw 8 dup(0)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,10h ;初始化数据段和栈段
mov ax,1 ;ax用于保存每行需要计算的次数,从第二行需要计算一次开始,每行增加一次
mov bx,0 ;bx用于定位行,从第一行开始
mov cx,9 ;循环9次计算剩余9行
;设正在计算的数字为(i,j)
s1: push cx ;保存第一层循环的状态
mov cx,ax ;第二层循环的次数(即为该行所需计算的数字个数)
mov si,0 ;si用于行中的定位,从第一个字节开始
s2: mov dx,[bx+si] ;复制(i-1,j-1)到dx
add dx,[bx+si+1] ;dx加上(i-1,j)
add bx,16 ;bx移动到下一行,即 i+=1
add si,1 ;si移动到下一个字,即 j+=1
mov [bx+si],dx ;将dx复制到(i,j)
sub bx,16 ;bx移动到上一行,即 i-=1 ,计算下一个数字
loop s2
add bx,16 ;bx移动到下一行,即 i+=1 ,计算下一行的数字
inc ax ;ax自增,下一行要计算的数量比上一行多1个
pop cx ;恢复第一层循环的状态
loop s1
mov ax,4c00h
int 21H
code ends
end start


程序运行前,数据段为全0

程序运行后