STACKS SEGMENT STACK
DW 200H DUP(?)
TOP LABEL WORD
STACKS ENDS --定义栈大小
DATAS SEGMENT
ARY DW 123,-54,267,251,55,9 --定义一串数字
COUNT EQU ($-ARY)/2 --表示ARY串的changdu
SUM DW ? --定义SUM变量存放累加和
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODE,SS:STACKS,DS:DATAS
MAIN PROC NEAR
MOV BX,OFFSET ARY --ARY的首地址传入BX
PUSH BX --BX进栈
MOV BX,COUNT --COUNT的值送入BX
PUSH BX --BX进栈
MOV BX,OFFSET SUM --SUM的首地址传入BX
PUSH BX --BX进栈
CALL PROADD --调用子程序PROADD
INT 20H
MAIN ENDP
PROADD PROC NEAR
PUSH BP --保存现场
MOV BP,SP --将SP的值送入BP中,用于后面通过BP读取数据,不改变SP的值
PUSH AX
PUSH CX
PUSH SI
PUSH DI --保存现场
MOV SI,[BP+8] --BP+8地址为ARY的首地址
MOV CX,[BP+6] --BP+6地址里存的是COUNT的值
MOV DI,[BP+4] --BP+4地址存着SUM的首地址
XOR AX,AX --AX清零,用于累加
NEXT: ADD AX,[SI] --进行累加
ADD SI,2 --地址后移
LOOP NEXT
MOV [DI],AX --将累加和存入SUM中
POP DI
POP SI
POP CX
POP AX
POP BP 回复现场
RET
PROADD ENDP
CODES ENDS
END MAIN
这里面最难的地方是怎么判断栈里面的内容,我画图简单解释一下:
这是一个栈,初始化的时候,SP指向的是栈顶同时也是最底部,当开始PUSH数据的时候,SP就会向上移动,我们可以看到程序中,最开始PUSH的元素是ARY的首地址其次是COUNT的值所以在调用子程序之前的栈内容是这样子的
然后调用子程序,首先要存源程序的下一条指令的地址值,然后再存其他的你想要存的内容
这时,我们把SP指向的地址位置送入BP,相当于BP用来标记这个位置,方便SP后面指向其他的位置
这时我们就可以很方便的看出,BP+8即为ARY的首地址、BP+6为COUNT的值、BP+4为SUM的首地址了