题目:将data段的数据写入到table段中,并计算21年中的人均收入(取整),结果也保存在table段中
assume cs:codesg,ds:data,es:table,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个字符串(4字节)
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型数据(4字节)
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型数据(2字节)
data ends
table segment
db 21 dup('year summ ne ?? ')
table ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
方案一:利用多重循环将数据写入table段中
(1).将段寄存器和各个段相连
codesg segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov ax,stack
mov ss,ax//将寄存器cx的值入栈保存,进行下次循环时拿出减一
mov sp,10H
//以上为将各个段与相应段寄存器相连
(2).循环的大致步骤
//大循环
mov cx,...
s:push cx
//中循环
mov cx,...
s1:push cx
mov cx,...
//小循环
s2:...
loop s2//最内层循环不用pop cx
//小循环
pop cx
loop s1
//中循环
pop cx
loop s
//大循环
(3)将年份和收入分别传入table中。(字节相同循环次数相同)
其中si表示data段的偏移地址,di表示table段的偏移地址,bx表示table段要存入的起始偏移地址
mov bx,0
mov si,0//用si表示data中偏移地址,di表示table中偏移地址
mov di,0
mov cx,2
s:push cx
//一个大循环(将年份和收入两种数据分别存入table中,对应上面cx=2)
mov cx,21
s1:push cx
mov cx,4
s2:mov al,ds:[si]//寄存器间接寻址
mov es:[bx+di],al//寄存器基址变址寻址
inc si
inc di
loop s2//最内层循环
add di,12//stack中数据按行存储(年份和收入为列)且字节为4,所以减去字节数
pop cx//非最内层循环需要出栈cx
loop s1
//一个大循环
mov bx,5
pop cx
loop s
(4)将雇员数传入table中。(字节为2,循环次数为2或直接用字寄存器一次存放)
bx表示table段要存入的起始偏移地址
mov bx,0AH
mov di,0//上段循环si已表示适当data段偏移地址,不需重设si
mov cx, 21
s1: mov ax,ds:[si]
mov es:[bx+di],ax
add si,2
add di,10H
loop s1
(5)基于table段数据计算人均收入(取整)并存入
雇员数为2字节数据,收入为4字节数据,则相除得的商用ax(字寄存器)存放,余数用dx高位存放
mov di,5
mov cx,21
s: mov dx,es:[di]
mov ax,es:[di].2//寄存器相对寻址
div word ptr es:[di].0AH
mov es:[di].0DH,ax
add di,10H
loop s
(6)尾部代码
mov ax,4c00h
int 21h
codesg ends
end start