編寫一個匯編語言程序,完成以下要求。從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 SEGMENTASSUME 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標簽處,否則執行下一條指令 即AXMOV 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 ;將最后的所有數據的和的結果賦值給AXIDIV BL ;IDIV帶符號的除法指令 隱含被除數為AX(存放著所有數的總和) 商為AL 余數為AHMOV AVE,AL ;將商(平均分的整數部分)賦值給AVEMOV AVE+1,AH;由于AVE為DB數據類型,下一個存儲單元+1即可,將AH余數(平均分的小數部分)賦值給AVE+1MOV AH,4CH ;DATA SEGMENT
string DB "Hello World!" ;將需要轉換的字符串存放到string中,定義類型為DB型
LEN EQU $-string ;等值偽指令EQU,將LEN表示string的長度
DATA ENDS
CODE SEGMENTASSUME CS:CODE,DS:DATA
START: MOV AX,DATA ;由于DATA為立即數,不能用賦值給段寄存器DS,需要借助AX通用寄存器MOV DS,AX ;將AX賦值給DSMOV BX,OFFSET string ;BX獲取string的有效地址用于取出string中的字符串MOV CL,LEN ;CL為string字符串的長度
NEXT: MOV AL,[BX] ;此時[BX]為string所存放字符串的內容,賦值給ALCMP 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 ENDSEND START