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的首地址了