汇编-实验:寻址方式在结构化数据访问中的应用

大方向

用bx,si指向data

用bp,di指向table

想过一次循环(cx=21)完成 1年的所有数据,发现有难度,data段的数据要不断跳到不同的一堆数据中去。之后改成一次循环(cx=21)只完成一类数据。

如此就需要4段 代码完成(在一个代码段中)

每一小段通过21次循环,完成一个21年的一类数据(eg:完成21个年份;完成21年各个年份的收入…)

~~~asm

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
assume cs:codesg,ds:datasg
datasg segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995' ;表示21年的21个字符串

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;总收入的21个数据

dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
datasg ends
tablesg segment
db 21 dup('year summ ne ?? ')
tablesg ends
;使用bp时,默认段地址是ss,所以ss:bp+di指向table,ds:bx+si指向数据
codesg segment
start:
mov ax,datasg
mov ds,ax ;data段的段地址
mov ax,tablesg
mov ss,ax ;table段的段地址

mov bp,0 ;bp,di表示table的地址
mov bx,0 ;bx,si表示data放的地址
mov si,0
mov di,0
mov cx,21
year: mov ax,[bx+si]
mov [bp+di],ax
add si,2
add di,2
mov ax,[bx+si]
mov [bp+di],ax
add si,2 ;第一年结束
add bp,16
mov di,0
loop year ;至此年份结束

mov cx,21
add bx,84
mov si,0
mov bp,0
summ: mov di,5
mov ax,[bx+si]
mov [bp+di],ax
add si,2
add di,2
mov ax,[bx+si]
mov [bp+di],ax
add si,2 ;第一年结束
add bp,16

loop summ ;至此收入结束

mov cx,21
add bx,84
mov si,0
mov bp,0
mov di,10
people: mov ax,[bx+si]
mov [bp+di],ax
add si,2 ;第一年结束
add bp,16
loop people

mov cx,21
mov bp,0
mov di,0

income:
mov ax,[bp+di+5] ;被除数的低八位
add di,2
mov dx,[bp+di+5] ;被除数的高八位
add di,3
div word ptr [bp+di+5] ;除数
add di,3
mov [bp+di+5],ax ;ax保存的是商,将商输入到table中
;第一年结束
add bp,16
mov di,0
loop income

mov ax,4c00H
int 21H
codesg 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
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


assume cs:code,ds:data,ss:stack

data segment

db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
;以上是表示21年的21个字符串 year


dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;以上是表示21年公司总收入的21个dword数据 sum

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

table segment
;0123456789ABCDEF
db 21 dup ('year summ ne ?? ')
table ends

stack segment stack
db 128 dup (0)
stack ends



code segment

start: mov ax,stack
mov ss,ax
mov sp,128 ;栈

mov ax,data
mov ds,ax ;data段的数据 ds

mov ax,table
mov es,ax ;tble段的数据 es

mov si,0 ;
;mov di,21*4 ;总收入 此处用si+21*4表示了(因为di表示的总收入也是4字节的所以可以用si代替)
mov bx,21*4 + 21*4 ;员工数
mov bp,0 ;tble段的偏移地址bp

mov cx,21
inputtable:
push ds:[si+0]
pop es:[bp+0]
push ds:[si+2]
pop es:[bp+2]
;年份的输入

mov ax,ds:[si+21*4+0] ;收入的输入
mov dx,ds:[si+21*4+2]
mov es:[bp+5],ax
mov es:[bp+7],dx

push ds:[bx] ;人员数的输入
pop es:[bp+0AH]

div word ptr ds:[bx] ;除法
mov es:[bp+0Dh],ax ;人均输入

add si,4
add bx,2
add bp,2
loop inputtable



mov ax,4C00H
int 21H



code ends



end start