王爽汇编(第三版)第8章试验7解析

首先书中给出了一段程序,并且定义好了一些数据。如下代码(以下称已知)

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),中英文的符号别搞错。反正耗了两天才弄好,有一天都是在报错中度过的。慢慢搞就理解了

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值