欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

编写一个汇编语言程序,完成以下要求。从BUF单元处定义有10个带符号字数据:-1,3,24,94,62,72,55,0,-48,99,试找出他们中的最大值和平均值,并以此分别存放至该数据区的后两个单元

程序员文章站 2022-03-10 08:22:42
...

编写一个汇编语言程序,完成以下要求。从BUF单元处定义有10个带符号字数据:-1,3,24,94,62,72,55,0,-48,99,试找出他们中的最大值和平均值,并以此分别存放至该数据区的后两个单元中(假设这10个数的和值不超过16位范围)

P176
4.12

编程思路:首先DATA段中,定义BUF为DW数据类型,因为存在带符号字数据,N为记录BUF的数据总个数,MAX为DW数据类型存放最大值,AVE为DB数据类型且占用两个物理单元,分别存放平均值的整数部分和小数部分;接着,使用SI获取BUF的有效地址,AX存放以次存放BUF中的数据,并且与下一个数据进行比较大小,若AX小于[SI]则将大的值[SI]赋值给AX,否则进行[SI+2]下一个数据进行与AX比较,AX始终存放BUF数据中的最大值;CX存放数据的总个数,DX依次存放BUF的数据相加之和;最后,将总数据之和/总个数=商(平均分的整数部分)存放在AVE中,余数(平均分的小数部分)存放在AVE+1中。

代码如下:

DATA	SEGMENT
BUF	DW -1,3,24,94,62,72,55,0,-48,99
N	EQU	($-BUF)/2	;由于定义的BUF为DW字类型,每个数据占两个物理单元,最后个数除以二,这里的N为BUF的长度
MAX	DW	?			;用于存放BUF中最大的数据值
AVE	DB	?	?		;由于题目规定平均值需要存放在最大值后,定义两个DB类型,第一个存放商(平均值的整数部分),第二个存放余数(平均值的小数部分)
DATA	ENDS
CODE	SEGMENT
		ASSUME	CS:CODE,DS:DATA
START:	MOV	AX,DATA	;由于DATA为立即数,DS为段寄存器,立即数不能直接给段寄存器赋值,需要引用AX通用寄存器
		MOV	DS,AX	;通用寄存器赋值给段寄存器
		LEA	SI,BUF	;LEA取有效地址指令。将源操作数的有效地址送到指令中指定的寄存器中,源操作数只能是存储器操作数,目的操作数只能是16位的通用寄存器
		CLC			;标志位操作指令CLC。CF=0,使进位标志位CF清零
		XOR	AX,AX	;AX清零操作
		XOR	DX,DX	;DX清零操作
		MOV	AX,[SI]	;将SI内容赋值给AX,即BUF中的内容,由于AX为16位通用寄存器,且BUF也为DW类型,一个数据占两个物理单元,即该指令操作是正确合法的
		MOV	CX,N	;CX为循环次数/BUF存放的数据个数
NEXT:	ADC	DX,[SI]	;由于BUF单元处定义的是带符号字数据,进行运算的时候需要相加,所以要使用ADC带进位的加法指令 即DX为所有数相加之后的和 用来存放最后的和的结果
		CMP	AX,[SI]	;比较AX和[SI]中的大小
		JGE	GOON	;若AX>=[SI]跳转大GOON标签处,否则执行下一条指令 即AX
		MOV	AX,[SI]	;执行到此条指令表[SI]要比AX大,需要将数值大的[SI]存到AX中,使得AX始终存放最大值
GOON:	ADD	SI,2	;由于BUF为DW数据类型,所以需要SI+2才可以指向下一个数据
		LOOP NEXT	;CX-1,若CX≠0,跳转 即接着比较下一个数
		MOV	MAX,AX	;执行到此指令表示数据已经全部比较完成,最大值存放在AX中
		MOV	BL,N	;BL为BUF的数据总个数
		MOV	AX,DX	;将最后的所有数据的和的结果赋值给AX
		IDIV BL		;IDIV带符号的除法指令 隐含被除数为AX(存放着所有数的总和) 商为AL 余数为AH
		MOV	AVE,AL	;将商(平均分的整数部分)赋值给AVE
		MOV	AVE+1,AH;由于AVE为DB数据类型,下一个存储单元+1即可,将AH余数(平均分的小数部分)赋值给AVE+1
		MOV	AH,4CH	;DATA	SEGMENT
string	DB	"Hello World!"	;将需要转换的字符串存放到string中,定义类型为DB型
LEN EQU $-string			;等值伪指令EQU,将LEN表示string的长度
DATA	ENDS
CODE	SEGMENT
		ASSUME	CS:CODE,DS:DATA
START:	MOV	AX,DATA	;由于DATA为立即数,不能用赋值给段寄存器DS,需要借助AX通用寄存器
		MOV	DS,AX	;将AX赋值给DS
		MOV	BX,OFFSET string	;BX获取string的有效地址用于取出string中的字符串
		MOV	CL,LEN	;CL为string字符串的长度
NEXT:	MOV	AL,[BX]	;此时[BX]为string所存放字符串的内容,赋值给AL
		CMP	AL,'a'	;由于是DB字节类型,只需要将AL的一个字节单元与单个字符'a'进行比较
		JB	LOP		;JB为小于跳转,即AL存放的字节单元的内容所对应的ASCII码值小于'a'所对应的ASCII码值,跳转到LOP标签处 否则不跳转执行下一条指令
		CMP	AL,'z'	;若执行到此条指令,代表AL>='a',接下来需要与'z'进行比较即可
		JA	LOP		;JA为大于跳转,即AL存放的字节单元的内容所对应的ASCII码值大于'z'所对应的ASCII码值,跳转到LOP标签处 否则不跳转执行下一条指令  
		SUB	AL,20H	;执行到此条指令,表示以及确定此时的AL为小写字母,AL-20H表示将小写字母转换为所对应的大写字母(小写字母比对应的大写字母的ASCII码值大20H)
		MOV	[BX],AL	;将小写字母转换为对应的大写字母结束后,结果AL存放回原来的物理地址[BX]处
LOP:	INC	BX		;BX+1(因为DB字节类型),表示判断下一个字节单元存放的字符串
		DEC	CL		;CL-1,表示字符串string所需要判断字符的长度减一
		JNZ	NEXT	;若CL不为0,即字符串string仍有需要判断的字符,跳转到NEXT标签处
		MOV	AH,4CH	;调用4CH号功能,返回DOS操作系统
		INT	21H		;终止当前程序的运行,并返回DOS系统
CODE	ENDS
		END	START
相关标签: 微机原理