例1:五个元素的DW数组ArrayA和ArrayB,把输入的存储到数组里。并且计算两个数相加的和除以2的结果。并输出。ArrayC[i]=(ArrayA[i]+ArrayB[i])/2
.MODEL SMALL
.STACK 100H
.DATA
;三个数组用于存放用户输入的两行和输出结果
ArrayA DW 5 DUP (?)
ArrayB DW 5 DUP (?)
ArrayC DW 5 DUP (?)
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV CX,5 ;存储循环次数
XOR SI,SI ;初始化SI
@INPUTA:
CALL INDECM ;调用INDECM用于键盘输入
MOV ArrayA[SI],AX ;把输入存储到数组ArrayA里
ADD SI,2 ;地址寄存器加2
LOOP @INPUTA ;继续循环
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV DL,'?'
INT 21H ;输出回车和问号
MOV CX,5 ;存储循环次数5
XOR SI,SI ;SI清空
@INPUTB:
CALL INDECM ;调用INDECM,键盘输入
MOV ArrayB[SI],AX ;把输入的存储到ArrayB里
ADD SI,2 ;地址寄存器加2
LOOP @INPUTB ;继续循环
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
MOV CX,5 ;存储循环次数5
XOR SI,SI ;SI清空
@OUTPUTC:
MOV AX,ArrayA[SI] ;把ArrayA[SI]存到AX去
ADD AX,ArrayB[SI] ;把ArrayB[SI]和AX相加,结果存到AX里
SAR AX,1 ;算术右移1位相当于带符号数除以2
MOV ArrayC[SI],AX ;把结果存到AX里
CALL OUTDECM ;输出AX
MOV AH,2
MOV DL,' '
INT 21H ;输出空格
ADD SI,2 ;地址加2
LOOP @OUTPUTC ;循环
MOV AH,4CH
INT 21H
MAIN ENDP
INCLUDE INDECM.ASM
INCLUDE OUTDECM.ASM
END MAIN
INDECM.ASM和OUTDECM.ASM 参看前面汇编(32)十进制的输入输出例子/INCLUDE 指令
代码比较简单,但是有个很重要的知识点:
SAR AX,1
算术右移一位,相当于带符号数除以2
例2:输入五个元素的DW数组,从大到小排序并输出
.MODEL SMALL
.STACK 100H
.DATA
ArrayA DW 5 DUP (?)
;定义一个5个元素的数组,初始值未定
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV CX,5 ;循环次数存储5
XOR SI,SI ;SI初始化
@INPUTA:
CALL INDECM ;键盘输入
MOV ArrayA[SI],AX ;把键盘输入的存储到ArrayA[SI]里
ADD SI,2 ;地址加2
LOOP @INPUTA ;循环
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
LEA SI,ArrayA ;取数组的地址
MOV BX,5 ;存储数组的大小
CALL SORT ;调用SORT进行排序
MOV CX,5
@OUTPUTA:
MOV AX,[SI] ;把数组的地址给AX
CALL OUTDECM ;调用OUTDECM输出
MOV AH,2
MOV DL,' '
INT 21H ;输出回车
ADD SI,2 ;地址寄存器加2,到下一个元素
LOOP @OUTPUTA
MOV AH,4CH ;结束
INT 21H
MAIN ENDP
INCLUDE INDECM.ASM
INCLUDE OUTDECM.ASM
;下面是SORT程序
SORT PROC
;入栈操作
PUSH BX
PUSH CX
PUSH DX
PUSH SI
DEC BX ;数组大小BX的值减1
JE @END_LOOP ;如果ZF=1(零标志位)就跳转
MOV DX,SI ;把数组的地址给DX
@LOOP_TOP:
MOV SI,DX ;把数组的地址给SI,相当于每次循环的时候是从数组的第一个开始的
MOV CX,BX ;BX的值给CX,用于循环
MOV DI,SI ;把数组的地址给DI
MOV AX,[SI] ;数组的第一个元素的值给AX
@FIND_SMALL:
ADD SI,2 ;地址加2
CMP [SI],AX ;把SI+2后的元素的值和AX做比较
JGE @NEXT ;如果大于或者等于就跳转NEXT
MOV DI,SI ;把这个更小的值的位置存到DI里
MOV AX,[DI] ;把新的最小值存到AX里
@NEXT:
LOOP @FIND_SMALL
CALL SWAP ;找出最小值AX以后调用SWAP
DEC BX ;BX减1
JNE @LOOP_TOP ;如果ZF=0(零标志位)就跳转
@END_LOOP:
POP SI
POP DX
POP CX
POP BX
RET
SORT ENDP
SWAP PROC
PUSH AX ;把AX推入堆栈中
;AX是新的最小的值,[DI]是新的最小的值的原本的位置上的数;[SI]代表用户输入的最后的一个数
MOV AX,[SI] ;把数组最后一个元素的值给AX
XCHG AX,[DI] ;把最小的元素的值和数组原本最后的元素交换值
;此时AX是最小的值,[DI]的值是最后一个元素,
MOV [SI],AX ;把最小的值AX给[SI],意味着现在数组最后一个元素是最小的值了
;此时最后一个元素是就是最小的那个数,而原本最小的那个数的位置成了以前的最后一个元素
;上面的注释写的是第一次循环的情况
POP AX ;出栈
RET
SWAP ENDP
END MAIN
如果要改成从小到大排序,只需要把71行的JGE改成JLE
例3:用INDECM,输入五个数。把第一个数和最后一个数相加除以2,输出 ArrayB[0]=(ArrayA[i]+ArrayA[i-1])/2;然后其余的数,按照ArrayB[i]=(ArrayA[i]+ArrayA[i-1])/2计算并输出
.MODEL SMALL
.STACK 100H
.DATA
ArrayA DW 5 DUP (?)
ArrayB DW 5 DUP (?)
;定义两个元素为5,初始值未定的数组
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV CX,5 ;循环次数CX存储5
XOR SI,SI ;初始化SI
@INPUTA:
CALL INDECM ;调用INDECM
MOV ArrayA[SI],AX ;把输入的存储到数组里
ADD SI,2 ;地址寄存器加2
LOOP @INPUTA ;循环
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;回车
MOV CX,5 ;存储循环次数5
XOR SI,SI ;SI清零
@REPEAT:
CMP SI,0
JE @THEN ;如果SI等于0就跳转THEN
MOV AX,ArrayA[SI] ;把ArrayA[SI]存到AX里
ADD AX,ArrayA[SI-2] ;把它前一个元素和AX相加
JMP @NEXT ;跳转NEXT
@THEN:
MOV AX,ArrayA[SI]
ADD AX,ArrayA[SI+8]
;把第一个和最后一个数相加
@NEXT:
SAR AX,1 ;把AX除以2
MOV ArrayB[SI],AX ;把结果存到ArrayB里
ADD SI,2 ;地址寄存器加2
LOOP @REPEAT ;继续循环
MOV CX,5 ;存储循环次数5
XOR SI,SI ;SI清空
@OUTPUTB:
MOV AX,ArrayB[SI] ;把ArrayB[SI]存入AX
CALL OUTDECM ;输出AX
MOV AH,2
MOV DL,' '
INT 21H ;输出问号
ADD SI,2 ;地址寄存器加2
LOOP @OUTPUTB ;循环
MOV AH,4CH
INT 21H
MAIN ENDP
INCLUDE INDECM.ASM
INCLUDE OUTDECM.ASM
END MAIN
例4:输入四名学生的三门成绩,输出平均值
.MODEL SMALL
.STACK 100H
.DATA
NUM DW 3
SCORES DW 4 DUP (?)
DW 4 DUP (?)
DW 4 DUP (?)
;定义3*4的二维数组用于存储成绩
AVG DW 4 DUP (?)
;AVG数组存储平均成绩
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
XOR BX,BX ;初始化BX
@IN_ROW:
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV CX,4 ;存储循环次数4
XOR SI,SI ;初始化SI
@IN_CLN:
CALL INDECM ;调用INDECM输入程序
MOV SCORES[BX][SI],AX ;把输入的数字存到数组里
ADD SI,2 ;地址寄存器加2
LOOP @IN_CLN ;循环
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;回车
ADD BX,8 ;BX加8(因为继续循环SI会被清零)
CMP BX,24
JL @IN_ROW ;如果BX小于24就继续IN_ROW
MOV SI,6 ;地址寄存器存6
@REPEAT:
MOV CX,3 ;记录循环次数3
XOR BX,BX ;BX清零
XOR AX,AX ;AX清零
@SUM:
ADD AX,SCORES[BX][SI] ;把SCORES[BX][SI]的值给AX,第一次的时候地址是6相当于是第一个人的最后一个成绩
ADD BX,8 ;BX加8也就是到了下一行
LOOP @SUM ;循环三次
XOR DX,DX ;DX初始化
DIV NUM ;做除法NUM=3
MOV AVG[SI],AX ;把结果存到AVG数组里,这个时候SI是和上面处理成绩数组的SI是一样的
SUB SI,2 ;地址寄存器SI减2
JNL @REPEAT ;如果进位位不被置位就跳转REPEAT
MOV CX,4 ;记录循环次数4
XOR SI,SI ;SI清零
@OUTPUT:
MOV AX,AVG[SI] ;把要输出的存放到AX里
CALL OUTDECM ;调用OUTDECM
MOV AH,2
MOV DL,' '
INT 21H ;回车
ADD SI,2 ;地址寄存器加2
LOOP @OUTPUT ;继续循环
MOV AH,4CH
INT 21H
MAIN ENDP
INCLUDE INDECM.ASM
INCLUDE OUTDECM.ASM
END MAIN
这里,计算平均值的时候,是从第一个人的最后一科成绩开始计算的,然后地址依次减2往前推,存入到AVG的时候的位置也是从后往前。输出的时候是从前往后