例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的时候的位置也是从后往前。输出的时候是从前往后

最后修改:2022 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏