分析:
1、首先要细心的将数据都输入进去,不能有任何差错,轻则语法报错,重则逻辑出错,需要费很大力才能将错误找出来,耽误编程效率
2、因为寄存器很少,所以我们要省着点用,能公用的就公用,不能公用的想着办法公用。
上面定义的数据段,我们可以看出有3个结构:年份、总收入、公司雇员人数。因为地址是连续的我们可以找到这几个结构的起始地址,相当于C语言中的结构体名分别为:年份=0;总收入:1*4*21=84;公司雇员人数:84+4*21=168。有了地址我们就可以定位了,也就是找到各数据的EA了,开始分配寄存器了:
年份:0[ bx+si ],虽然年份定义的是字节单元,但是每个年份都是4个,所以我们需要用循环才能将年份放到table段的相应位置,所以我们用两个寄存器来表示年份的偏移地址,bx 每循环四次增加1,指向下个年份,si 就是指向每个年份的四个数字。
总收入:84[ bx ] ,总收入是双字类型的单元,也是每四次增加1,其起始地址是84
雇员数:168[ di ] ,雇员数是字单元类型的,所以我给它单独分配了个寄存器,不过我现在发现用 [ bx/2 ] 也可以来表示,又可以省个寄存器
table:es:[ bp + idata] ,idata分别有几个关键数值,对应表格中的地址,因都是固定的,不用寄存器。而 hp 对应的是表格每行的起始地址。
这样就可以编程了,根据前面王爽老师讲的技巧,要有结构体方面的编程意识,灵活运用偏移地址不同格式。
1、我先定义了一个堆栈段,因为有嵌套循环,肯定要把计数器的值压到里面保存,也以防可能有别的用处,定义16个字节足以(如果程序不太大的话)
2、初始化别忘了,段地址和偏移地址要用的寄存器
start: mov ax,stack ;stack
mov ss,ax
mov sp,10h
mov ax,data
mov ds,ax ;data
mov ax,table
mov es,ax ;table
mov bx,0 ;
mov bp,0
mov si,0
mov di,0
mov cx,21
3、接下来就是循环,首先把计数器压栈了
push cx
4、接下来循环输入年份到表格对应位置
mov cx,4 ;year
s1: mov al,[bx+si]
mov byte ptr es:[bp+si],al
inc si
loop s1
5、后面因为我们要作除法,所以提前把收入放到 AX 和 DX 中,又因为后面要用到 ax 转存数值,所以先把 ax 压栈,后面再取出来。
;income
mov ax,84[bx]
mov es:[bp+5],ax
push ax
mov dx,84[bx+2]
mov es:[bp+7],dx
6、这里将总收入除以雇员,将得到的数值放到对应的地址
;average income
pop ax
div word ptr es:[bp+0ah]
mov word ptr es:[bp+0dh],ax
7、剩下的就是把对应用作偏移地址的寄存器加对应的值,预备下一次循环
add bp,10h
add bx,4
add di,2
mov si,0
pop cx
loop s0
以下是完整代码
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'
;year/21 这里我开始没有将逗号写出来,后来发现 ' 符号也输入进去了
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;gross income/21
dw 3,7,9,12,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;employee/21 输入数据一定要小心细心,否则div的时候容易报错“divide overflow” 意思是说AX放不下商了
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
codesg segment
start: mov ax,stack ;stack
mov ss,ax
mov sp,10h
mov ax,data
mov ds,ax ;data
mov ax,table
mov es,ax ;data store
mov bx,0 ;这里我把能用来当作偏移地址的寄存器都用上了,能力不够,寄存器来凑
mov bp,0
mov si,0
mov di,0
mov cx,21
s0: push cx ;嵌套循环肯定需要把外层计数器给压栈了
mov cx,4 ;year
s1: mov al,[bx+si]
mov byte ptr es:[bp+si],al
inc si
loop s1
;income
mov ax,84[bx]
mov es:[bp+5],ax
push ax
mov dx,84[bx+2]
mov es:[bp+7],dx
;employee
mov ax, 168[di]
mov word ptr es:[bp+0ah],ax
;average income
pop ax
div word ptr es:[bp+0ah]
mov word ptr es:[bp+0dh],ax
add bp,10h
add bx,4
add di,2
mov si,0
pop cx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
输出结果为