首先书中给出了一段程序,并且定义好了一些数据。如下代码(以下称已知)
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,14257,17800
;以上表示是21年公司雇员人数的21个word型数据
data ends
table segment
db 21 dup('year summ ne ?? ')
table ends
试验要求:编程将data段中的数据按照如下的格式写到table段中,并计算21年中的人均收入(取整),结果也按照下面的格式保存在table段中
首先我分析一下数据的存储情况,由已知 得 0~83 (十进制) 内存单元 存储的是21个字符串 //21年
;解释 由于0~9单个数字是占1个字节(两位16进制),所以21个字符串(4位数字)总共占 21*4=84(个)字节 由于内存单元的地址开始是从0 开始的,所以是0~83 在内存中准确的表示 data:0000 ~ data:0053 (83在16进制是53)。
84~167(10进制) 内存单元 存储的是 21 个 dword 型数据 //21年公司总收入
;解释 dword 类型的数据 占4个字节(八位16进制) 总共占 21*4=84(个)字节 例如 已知中16 在数据段表示为 10 00 00 00 同理在内存中84~167 也要化成上面16进制的形式,当然这个试验中我并不需要把它们化成16进制。
最后 168~209 (十进制) 内存单元 存储的是 21个word 型数据 //21年公司雇员数量
;解释 word 类型的数据占2个字节, 总共占 21*2=42(个)字节
用debug 测试下
和分析的情况一样
然后运用数组的知识,把数据写到table段中
首先我们要把4个字节的21个字符串,写到table段中,由于我们的寄存器只能存储2个字节,所以我们分开两次分别存储。
我用的是 ds:[bx+idata] ;关于idata 这里可以直接用10进制的数字(16进制要记得加个H),在程序加载处理的时候会把10进制换算成16进制 例如 ds:[bx+10] 和ds:[bx+0ah] 等价,其他正确的写法也可以。
21个dword型数据 和 21个word型数据 也是同理 写道table段中 ;这里就不再赘述了
在然后是人均收入这块,ax 存放低16位,dx存放高16位,不要搞反了,仔细看下面代码
由于 mov bx,es:[bx+10] 该语句执行后bx的值将会改变,所以在这前我们把bx压入栈中(push bx),然后到后面在弹出(pop bx)。
后面循环 add bx,16等不懂的,重新看前面红色字体(结合图片食用更佳)
codesg segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov ax,stack
mov ss,ax
mov sp,16
mov si,0
mov bx,0
mov di,0
mov cx,21
s:
mov dx,ds:[di+0]
mov es:[bx+0],dx
mov dx,[di+2]
mov es:[bx+2],dx ;解决年份
mov dx,[di+84]
mov es:[bx+5],dx
mov dx,[di+86]
mov es:[bx+7],dx ;解决收入
mov dx,[si+168]
mov es:[bx+10],dx ;解决雇员
mov ax,es:[bx+5]
mov dx,es:[bx+7]
push bx
mov bx,es:[bx+10]
div bx
pop bx
mov es:[bx+13],ax ;解决人均收入
add bx,16
add di,4
add si,2
loop s
mov ax,4c00h
int 21h
codesg ends
我们把总的程序运行下,运行结果如下
总的代码如下
assume cs:codesg ,ds:data,ss:stack,es: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'
;以上表示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,14257,17800
;以上表示是21年公司雇员人数的21个word型数据
data ends
table segment
db 21 dup('year summ ne ?? ')
table ends
stack segment
db 16 dup(0)
stack ends
codesg segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov ax,stack
mov ss,ax
mov sp,16
mov si,0
mov bx,0
mov di,0
mov cx,21
s:
mov dx,ds:[di+0]
mov es:[bx+0],dx
mov dx,[di+2]
mov es:[bx+2],dx ;解决年份
mov dx,[di+84]
mov es:[bx+5],dx
mov dx,[di+86]
mov es:[bx+7],dx ;解决收入
mov dx,[si+168]
mov es:[bx+10],dx ;解决雇员
mov ax,es:[bx+5]
mov dx,es:[bx+7]
push bx
mov bx,es:[bx+10]
div bx
pop bx
mov es:[bx+13],ax ;解决人均收入
add bx,16
add di,4
add si,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
我在搞着实验的时候,报了好多错。错误范例比如:ds:[ax+idata] (ax不能用做替代bx不懂把书翻到P161),mov dword ptr es:[bx+idata],[di+idata] (这个会报警告,不明白就把书翻到P51),中英文的符号别搞错。反正耗了两天才弄好,有一天都是在报错中度过的。慢慢搞就理解了