汇编语言(第三版)王爽著(实验七)寻址方式在结构化数据访问中的应用
一、实验目的
学习如何编写,调试具有多个段的程序。
二、实验设备与环境
计算机
DOS操作系统或 Windows 操作系统
MASM.EXE, LINK.EXE, DEBUG.COM 或宏汇编集成环境
- 实验内容、程序清单及运行结果
Power idea公司从1975年成立一直到1995年的基本情况如下。
年份 收入(千美元) 雇员(人) 人均收入(千美元)
1975 16 3 ?
1976 22 7 ?
1977 382 9 ?
1978 1356 13 ?
1979 2390 28 ?
1980 8000 38 ?
……
1995 5937000 17800 ?
下面的程序中,已经定义好了这些数据:
DATAS 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年公司总收入的21个word型数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,11430,15257,17800
;以上是表示21年公司雇员的21个word型数据
DATAS ENDS
table SEGMENT
db 21 dup('year summ ne ?? ')
table ENDS
编程,将data段中的数据按如下格式写入到table段中,并计算21年的人均收入(取整)
实验代码:
assume cs:codesg,ds:data
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'
;84字节
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;84字节
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
db 21 dup('year summ ne ?? ')
table ends
codesg segment
start: mov ax,data
mov ds,ax
sub bx,bx
sub di,di
mov cx,21
;日期导入
s: mov ax,ds:[di]
mov ds:[bx+224],ax;224为从data段起始跳到table起始
add di,2;日期为四个字节一组,而16位寄存器最大只能存两个字节,所以每次加二
mov ax,ds:[di]
mov ds:[bx+226],ax
add di,2
add bx,16;在table字段里换行输入日期
loop s
sub bx,bx
mov cx,21
;收入导入
d: mov ax,ds:[di];此di是上段循环最后的di,没有重置
mov ds:[bx+229],ax;229为从data段起始跳到table段收入输入的起始
add di,2;收入为四个字节一组,而16位寄存器最大只能存两个字节,所以每次加二
mov ax,ds:[di]
mov ds:[bx+231],ax
add di,2
add bx,16;在table字段里换行输入收入
loop d
sub bx,bx
mov cx,21
;雇员数导入
e: mov ax,ds:[di];此di是上段循环最后的di,没有重置
mov ds:[bx+234],ax;234为从data段起始跳到table雇员数输入的起始
add di,2
add bx,16;在table字段里换行输入雇员数
loop e
sub di,di;数据来源不再是数据段的顺序读取
sub bx,bx
sub si,si
mov cx,21
;人均收入导入
g: mov ax,ds:[di+84];定位到收入起始,将收入数据导入ax,dx中
mov dx,ds:[di+86]
div word ptr ds:[si+168];定位到雇员数起始
mov ds:[bx+237],ax;将算数结果存入table的人均收入位置
add di,4
add si,2
add bx,16;在table字段里换行输入人均收入
loop g
mov ax,4c00h
int 21h
codesg ends
end start
第一个循环执行年份输入,第二个收入输入,第三个雇员数输入,第四个人均收入输入,在人均收入的数据获取时使用div除法运算得到数据源
运行截图:
原来的样子
后来的样子
实验结论和体会:
在没有使用标号的情况下,要设计上面的程序,就要通过计算得出相关数据的位置,第一个循环执行年份输入,第二个收入输入,第三个雇员数输入,第四个人均收入输入,在人均收入的数据获取时使用div除法运算得到数据源
通过这次实验体会了没有标号的繁琐,这从侧面体现了标号的便捷