下面的程序中,已经定义好了这些数据
;实验七 寻址方式在结构化数据访问中的应用
;编程 将data段中的数据 按照如下格式写到table段中,并计算21年中的人均收入(取整)
;结果也按照下面的格式保存在table段中
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 21*4=84
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个数据 21*4=84
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
;以上是表示21年公司的员工数量
data ends
table segment
; '0123456789ABCDEF'
db 21 dup('year sumn ne ?? ')
table ends
stack segment stack
db 128 dup (0)
stack ends
先用debug查看这些数据在内存中的分布
;实验七 寻址方式在结构化数据访问中的应用
;编程 将data段中的数据 按照如下格式写到table段中,并计算21年中的人均收入(取整)
;结果也按照下面的格式保存在table段中
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个数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
;以上是表示21年公司的员工数量
data ends
table segment
; '0123456789ABCDEF'
db 21 dup('year sumn 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 ;数据从哪里来
mov ax,table
mov es,ax ;数据到哪里去
mov si,0
;年份在data中'1975'中的1偏移地址为0 ;ds:[si]
mov di,84
;公司总收入的第一个数据16,它的偏移地址在data段中是84(54H) ;ds:[di]
mov bx,168
;公司的员工数量,第一个数据3,在data段中的偏移地址是168(A8H) ;ds:[bx]
mov bp,0
;'year sumn ne ?? '的第一个字母y,在table段中的偏移地址是0 ;es:[bp]
;bp寄存器默认的段寄存器是ss,bp为偏移地址->ss:[bp]
mov cx,21;处理21行
;处理年份
inputtable: push ds:[si]
pop es:[bp]
push ds:[si+2]
pop es:[bp+2]
;处理总收入——低16位放在AX,高16位放在DX
mov ax,ds:[di]
mov dx,ds:[di+2]
mov es:[bp+5],ax
mov es:[bp+7],dx
; '0123456789ABCDEF'
;db 21 dup('year sumn ne ?? ') ;低位放到5,高位放到7
;处理员工数量
push ds:[bx]
pop es:[bp+0AH]
;这里用div 内存 ;因为寄存器不够用了
div word ptr ds:[bx]
mov es:[bp+0DH],ax
add si,4
add di,4
add bx,2
loop inputtable
mov ax,4c00h
int 21h
code ends
end start
代码改进:增加了代码可读性,已经减少寄存器的使用
;实验七 寻址方式在结构化数据访问中的应用
;编程 将data段中的数据 按照如下格式写到table段中,并计算21年中的人均收入(取整)
;结果也按照下面的格式保存在table段中
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个数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
;以上是表示21年公司的员工数量
data ends
table segment
; '0123456789ABCDEF'
db 21 dup('year sumn 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
mov ax,table
mov es,ax
mov si,0
;年份在data中'1975'中的1偏移地址为0 ;ds:[si]
mov di,21*4
;公司总收入的第一个数据16,它的偏移地址在data段中是84(54H) ;ds:[di]
mov bx,21*4+21*4
;公司的员工数量,第一个数据3,在data段中的偏移地址是168(A8H) ;ds:[bx]
mov bp,0
;'year sumn ne ?? '的第一个字母y,在table段中的偏移地址是0 ;es:[bp]
;bp寄存器默认的段寄存器是ss,bp为偏移地址->ss:[bp]
mov cx,21;处理21行
;处理年份
inputtable: push ds:[si+0]
pop es:[bp+0]
push ds:[si+2]
pop es:[bp+2]
;处理总收入——低16位放在AX,高16位放在DX
mov ax,ds:[si+21*4]
mov dx,ds:[si+21*4+2]
mov es:[bp+5],ax
mov es:[bp+7],dx
; '0123456789ABCDEF'
;db 21 dup('year sumn ne ?? ') ;低位放到5,高位放到7
;处理员工数量
push ds:[bx]
pop es:[bp+0AH]
;这里用div 内存 ;因为寄存器不够用了
div word ptr ds:[bx]
mov es:[bp+0DH],ax
add si,4
; add di,4
add bx,2
loop inputtable
mov ax,4c00h
int 21h
code ends
end start
具体代码:
assume cs:codesg,ds:data,ss:table
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'
;定义字节数据,存放年
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;定义双字数据,存放收入(被除数)。
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
;定义字形数据,存雇员人数(除数)。
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
;定义字形数据,21个年平均值
codesg segment
start: mov ax,data
mov ds,ax
;初始数据段
mov ax,table
mov ss,ax
;将表格定位给栈段(用栈段存放平均值)
mov bx,0
mov si,0 ;数据段中年份中的数据
mov bp,0 ;表格第一行
mov cx,21 ;21行所以21次循环
s0:mov ax,[bx+si] ;读取数据段中的年份数据的前2个字节,交给AX
mov [bp+0],ax ;年份数据的前2个字节放入到表格(因为表格前面定义给了SS栈段)
add si,2 ;指向年份后2个字节
mov ax,[bx+si] ;读取数据段中年份数据的后2个字节,交给AX
mov [bp+2],ax ;年份数据的后2个字节放入到表格
add si,2 ;指向数据段中下一个年份
add bp,10h ;转到下一行
loop s0
;S0循环是将数据段中(0-53H)的年份读取出来,放到表格的年份(0-3)列中
mov cx,21 ;21次循环处理收入
mov bp,0 ;收入的行
mov si,0 ;数据段中收入数据指针
s1:mov ax,[bx+si+84] ;因为数据段中年份数据是21行4个字节,共占了数据段84个字节。
;所以收入第一个数据是从数据段第84个字节处开始的,读取后给AX。
mov [bp+5],ax ;收入数据放入到表格,因为年份占了前4列,加上空格,所以放到第5列
add si,2 ;处理数据的后2个字节
mov ax,[bx+si+84] ;读取数据的后2个字节,放入AX
mov [bp+7],ax ;收入数据的后2个字节放入到表格
add si,2 ;指向下一个数据
add bp,10h ;指向下一行
loop s1
;S1循环是将数据段中(54H-0A7H)的收入读取出来,放到表格的收入(5-8)列中
mov cx,21 ;21次循环
mov bp,0 ;定位表格的行
mov si,0 ;数据段中雇员数据指针
s2:mov ax,[bx+si+168] ;因为数据段中年份与收入数据共占了168个字节。
;所以雇员第一个数据是从数据段第168个字节处开始的,读出给AX
mov [bp+10],ax ;将雇员数据放入到表格
add si,2 ;指向数据段下一个雇员数据
add bp,10h ;指向下一行
loop s2
;S2循环是将数据段中(0A8H-0D1H)的雇员读取出来,放到表格的收入(A-B)列中
mov cx,21 ;21次循环,计算平均收入值
mov bp,0
s3:mov ax,[bp+5]
mov dx,[bp+7] ;放入被除数(收入),高位给DX,低位给AX
div word ptr [bp+10] ;放入除数(雇员)
mov [bp+13],ax ;商(平均值)放入表格
add bp,10h ;指向下一行
loop s3
;S2循环是计算平均值,放到表格的人均收入(D-E)列中
mov ax,4c00h
int 21h
codesg ends
end start