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