汇编语言(王爽第三版)实验七

实验七

题目

Power idea公司从1975年成立一直到1995年的基本情况如下。

年份收入(千美元)雇员(人)人均收入(千美元)
1975163?
1976223?
19773823?
197813563?
197923903?
198080003?
1995593700017800?
下面的程序中,已经定义好了这些数据:
assume cs:codesgdata segmentdb '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,197514dd 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,8226dw 11542,14430,15257,17800;以上是表示21年公司雇员人数的21个word型数据data endstable segmentdb 21 dup('year summ ne ?? ')
table ends		end start

编程,将data段中的数据按如下格式写入到table段中,并计算21年中的人均收入(取整),结果也按照下面的格式保存在table段中。
在这里插入图片描述

思路

先确定一下数据的存放地址。
data段:
年份的数据占了21*4=84=54H。" db ‘1975’ “相当于"db 31H 39H 37H 35H”,“1”、“9”、“7”、"5"的ASCII码分别为31H 39H 37H 35H。
收入的数据占了21*4=84=54H。dword(双字节)型数据占4个字节32位。
雇员的数据占了21*2=42=2AH。word型数据占2个字节16位
由此可知,年份是0H~53H,收入是54H~A7H,雇员是A8H~D1H。
且有以下关系:

  1. data段地址+84(年份所占字节)=收入的数据起始地址
  2. data段地址+168(年份所占自己+收入所占字节)=雇员的数据起始地址

data段的数据占了DFH个字符,所以table段从E0H开始
如下图所示:
在这里插入图片描述

最暴力的方法就是4个循环21次分别把年份,收入,雇员数,人均收入存入table段中,刚开始想着能不能只循环一个21次就把所有数据插入table段中,结果发现似乎不太行。但是可以把年份和收入放在同一个循环中,然后雇员放在一个循环,平均收入放在一个循环,三个循环就解决了。
注意到年份和收入都是四字节,也就是他们可以同时使用一个增量di。由题目给的图可以知道数据要放在table段中的哪些位置。
程序如下:

assume cs:codesgdata segmentdb '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,197514dd 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,8226dw 11542,14430,15257,17800;以上是表示21年公司雇员人数的21个word型数据data endstable segmentdb 21 dup('year summ ne ?? ')
table ends		codesg segmentstart:mov ax,datamov ds,axmov ax,tablemov es,axsub bx,bxsub di,dimov cx,21dateIncome:mov ax,ds:[di]				;年的前2个字节mov es:[bx],ax			mov ax,ds:[di+84]			;收入的前2个字节mov es:[bx+5],axadd di,2mov ax,ds:[di]				;年的后2个字节mov es:[bx+2],ax		mov ax,ds:[di+84]			;收入的后两个字节mov es:[bx+7],axadd di,2add bx,16loop dateIncomemov cx,21sub bx,bxsub di,dig:							;雇员mov ax,ds:[di+168]mov es:[bx+10],axadd di,2add bx,16loop gAvemov cx,21sub bx,bxsub di,disub si,siave:mov ax,ds:[di+84]			;收入低16位mov dx,ds:[di+84+2]			;收入高16位div word ptr ds:[si+168]	;雇员数mov es:[bx+13],ax			;商放axadd di,4add si,2add bx,16loop avemov ax,4c00Hint 21Hcodesg endsend start

运行结果如下
在这里插入图片描述

改进

可以发现雇员和收入都是两个字节,考虑一下两者是否可以结合。整体上来看即从三个21次循环改为二个21次循环。

如下图所示,相同颜色的都可以整合:
在这里插入图片描述
整合如下:
在这里插入图片描述
程序如下:

assume cs:codesgdata segmentdb '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,197514dd 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,8226dw 11542,14430,15257,17800;以上是表示21年公司雇员人数的21个word型数据data endstable segmentdb 21 dup('year summ ne ?? ')
table ends		codesg segmentstart:mov ax,datamov ds,axmov ax,tablemov es,axsub bx,bxsub di,dimov cx,21dateIncome:						;处理年份和收入mov ax,ds:[di]				;年份的前2个字节mov es:[bx],ax			mov ax,ds:[di+84]			;收入的前2个字节mov es:[bx+5],axadd di,2mov ax,ds:[di]				;年份的后2个字节mov es:[bx+2],ax		mov ax,ds:[di+84]			;收入的后两个字节mov es:[bx+7],axadd di,2add bx,16loop dateIncomemov cx,21sub bx,bxsub di,disub si,sigAve:							;处理雇员和平均收入mov dx,ds:[si+168]			;雇员的全部字节mov es:[bx+10],dxmov ax,ds:[di+84]			;收入的前两个字节mov dx,ds:[di+84+2]			;收入的后两个字节div word ptr ds:[si+168]mov es:[bx+13],axadd di,4add si,2add bx,16loop gAvemov ax,4c00Hint 21Hcodesg endsend start

再改进

上面的改进已经把三个21次循环改为两个21次循环。在观察一下看看能不能把程序改进为在一个21次循环里就把所有数据插入table段中。

如下图所示:
在这里插入图片描述
改进成:
在这里插入图片描述
发现还可以在改进,即直接用[bx+2]来获取年份的后两个字节,[di+84+2]来获取收入的后两个字节。

如下所示:
在这里插入图片描述
改进后的代码更加容易阅读。
完整代码如下:

完整版

assume cs:codesgdata segmentdb '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,197514dd 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,8226dw 11542,14430,15257,17800;以上是表示21年公司雇员人数的21个word型数据data endstable segmentdb 21 dup('year summ ne ?? ')
table ends		codesg segmentstart:mov ax,datamov ds,axmov ax,tablemov es,axsub bx,bxsub di,disub si,simov cx,21all:						;年份存入table段mov dx,ds:[di]				;年份的前2个字节mov es:[bx],dx	mov dx,ds:[di+2]			;年份的后2个字节mov es:[bx+2],dx		;收入存入table段mov ax,ds:[di+84]			;收入的前2个字节 ;将收入的前两个字节放入axmov es:[bx+5],ax			mov dx,ds:[di+84+2]			;收入的后两个字节 ;将收入的后两个字节放入dxmov es:[bx+7],dx;雇员数存入table段mov bp,ds:[si+168]			;雇员的全部字节mov es:[bx+10],bp;人均收入存入table段div bp	;计算平均收入mov es:[bx+13],axadd di,4add si,2add bx,16loop allmov ax,4c00Hint 21Hcodesg endsend start

运行结果:
在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部