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

本文通过汇编语言程序实现对公司1975年至1995年间年度收入、员工数量等数据的处理与分析,计算每年的人均收入,并将结果以特定格式存储。通过不断优化程序,最终实现在一次循环内完成所有数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验七

题目

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

年份收入(千美元)雇员(人)人均收入(千美元)
1975163?
1976223?
19773823?
197813563?
197923903?
198080003?
1995593700017800?
下面的程序中,已经定义好了这些数据:
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,15257,17800
	;以上是表示21年公司雇员人数的21个word型数据

data ends

table segment
	db 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: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,15257,17800
	;以上是表示21年公司雇员人数的21个word型数据

data ends

table segment
	db 21 dup('year summ ne ?? ')
table ends		

codesg segment

start:
	mov ax,data
	mov ds,ax
	mov ax,table
	mov es,ax

	sub bx,bx
	sub di,di

	mov cx,21

dateIncome:
	mov ax,ds:[di]				;年的前2个字节
	mov es:[bx],ax			

	mov ax,ds:[di+84]			;收入的前2个字节
	mov es:[bx+5],ax
	add di,2

	mov ax,ds:[di]				;年的后2个字节
	mov es:[bx+2],ax		

	mov ax,ds:[di+84]			;收入的后两个字节
	mov es:[bx+7],ax
	add di,2

	add bx,16
	loop dateIncome

	mov cx,21
	sub bx,bx
	sub di,di

  g:							;雇员
	mov ax,ds:[di+168]
	mov es:[bx+10],ax

	add di,2

	add bx,16
	
	loop gAve

	mov cx,21
	sub bx,bx
	sub di,di
	sub si,si
	
ave:
	mov ax,ds:[di+84]			;收入低16位
	mov dx,ds:[di+84+2]			;收入高16位
	div word ptr ds:[si+168]	;雇员数
	mov es:[bx+13],ax			;商放ax

	add di,4
	add si,2
	add bx,16

	loop ave

	mov ax,4c00H
  	int 21H


codesg ends

end start

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

改进

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

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

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,15257,17800
	;以上是表示21年公司雇员人数的21个word型数据

data ends

table segment
	db 21 dup('year summ ne ?? ')
table ends		

codesg segment

start:
	mov ax,data
	mov ds,ax
	mov ax,table
	mov es,ax

	sub bx,bx
	sub di,di

	mov cx,21

dateIncome:						;处理年份和收入
	mov ax,ds:[di]				;年份的前2个字节
	mov es:[bx],ax			

	mov ax,ds:[di+84]			;收入的前2个字节
	mov es:[bx+5],ax
	add di,2

	mov ax,ds:[di]				;年份的后2个字节
	mov es:[bx+2],ax		

	mov ax,ds:[di+84]			;收入的后两个字节
	mov es:[bx+7],ax
	add di,2

	add bx,16
	loop dateIncome

	mov cx,21
	sub bx,bx
	sub di,di
	sub si,si

gAve:							;处理雇员和平均收入
	mov dx,ds:[si+168]			;雇员的全部字节
	mov es:[bx+10],dx

	mov ax,ds:[di+84]			;收入的前两个字节
	mov dx,ds:[di+84+2]			;收入的后两个字节
	div word ptr ds:[si+168]
	mov es:[bx+13],ax

	add di,4
	add si,2
	add bx,16
	
	loop gAve

	mov ax,4c00H
  	int 21H


codesg ends

end start

再改进

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

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

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

完整版

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,15257,17800
	;以上是表示21年公司雇员人数的21个word型数据

data ends

table segment
	db 21 dup('year summ ne ?? ')
table ends		

codesg segment

start:
	mov ax,data
	mov ds,ax
	mov ax,table
	mov es,ax

	sub bx,bx
	sub di,di
	sub si,si

	mov cx,21

all:						
	;年份存入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个字节 ;将收入的前两个字节放入ax
	mov es:[bx+5],ax			
	mov dx,ds:[di+84+2]			;收入的后两个字节 ;将收入的后两个字节放入dx
	mov es:[bx+7],dx

	;雇员数存入table段
	mov bp,ds:[si+168]			;雇员的全部字节
	mov es:[bx+10],bp

	;人均收入存入table段
	div bp	;计算平均收入
	mov es:[bx+13],ax

	add di,4
	add si,2
	add bx,16
	loop all

	mov ax,4c00H
  	int 21H


codesg ends

end start

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

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值