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

编写一个汇编语言程序,完成以下要求。从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

猜你喜欢

转载自blog.csdn.net/qq_41264055/article/details/103656116
今日推荐