前言:本实验为王爽老师的《汇编语言》第三版中的实验7(p172)
实验环境:DOSBox 0.74-3
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 | ? |
下面的程序中,已经定义好了这些数据:
assume cs:codesg
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个字符串
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型数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;以上是表示21年公司雇员人数的21个word型数据
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
编程,将 data 段中的数据按如下格式写入到 table 段中,并计算 21 年中的人均收入(取整),结果也按照下面的格式保存到在table 段中。
提示,可将 data 段中的数据看成是多个数组,而将 table 中的数据看成是一个结构型数据的数组,每个结构型数据中包含多个数据项。可用 bx 定位每个结构型数据,用 idata 定位数据项,用 si 定位数组项中的每个元素,对于 table 中的数据的访问可采用[bx].idata和[bx].idata[si]的寻址方式。
注意,这个程序是到目前为止最复杂的程序,它几乎用到了我们以前学过的所有知识和编程技巧。所以,这个程序是对我们从前学习的最好的实践总结。请认真完成。
完整代码:
assume cs:code,ds:data,es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985'
db '1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
;21个年份字符串(0-53h),一个数据占4个字节
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980,590827
dd 803530,1183000,1843000,2759000,3753000,4649000,5937000
;对应的收入(54h-0a7h),一个数据占4个字节
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;对应的员工数(0a8h-0d1h),一个数据占2个字节
data ends
table segment
db 21 dup ('year summ ne ?? ') ;总共21*16个字节 00h-0fh
; 10h-1fh
; 20h-2fh
; ...
; 140h-14fh
table ends
code segment
start: mov ax,data
mov ds,ax ;data段数据位于ds段
mov ax,table
mov es,ax ;table段数据位于es段
mov bx,0 ;每次循环add bx,4 进入data段下一年的数据(年份和收入)
mov si,0 ;每次循环add si,2 进入data段下一年的数据(员工数)
mov di,0 ;每次循环add di,10h 进入table段的下一组数据
mov cx,21 ;21年即21次循环
s: mov al,[0+bx]
mov es:[di+0],al
mov al,[1+bx]
mov es:[di+1],al
mov al,[2+bx]
mov es:[di+2],al
mov al,[3+bx]
mov es:[di+3],al ;将data段中年份通过al copy到table段
mov ax,[0a8h+si] ;ax暂时未使用,先利用ax存放员工数,避免存放收入时导致ax无法使用,避免使用栈
mov es:[di+0ah],ax ;将data段中员工数copy到table段
mov ax,[54h+bx]
mov dx,[56h+bx] ;收入为4个字节32位,高16位位于dx,低16位位于ax
mov word ptr es:[di+5],ax
mov word ptr es:[di+7],dx ;将data段中收入copy到table段
div word ptr es:[di+0ah] ;收入(dx+ax)除以员工数(es:[di+0ah]/[0a8h+si])
mov es:[di+0dh],ax ;商(人均收入)位于ax,将人均收入copy到table段
add bx,4 ;进入年份、收入的下一组数据
add si,2 ;进入员工数的下一组数据
add di,10h ;进入下一年份的
loop s
code ends
end start