Q. Example on Passing Parameters through Stack?
PROGRAM: Version 3
DATA_SEG SEGMENT
BCD DB 25h; Storage for BCD test value
BIN DB? ; Storage for binary value
DATA_SEG ENDS
STACK_SEG SEGMENT STACK
DW 100 DUP (0); Stack of 100 words
TOP_STACK LABEL WORD
STACK_SEG ENDS
CODE_SEG SEGMENT
ASSUME CS: CODE_SEG, DS: DATA_SEG, SS: STACK_SEG
START: MOV AX, DATA ; Initialise data segment
MOV DS, AX ; using AX register
MOV AX, STACK-SEG. ; initialise stack segment
MOV SS, AX ; using AX register
MOV SP, OFFSET TOP_STACK; initialise stack pointer
MOV AL, BCD ; Move BCD value into AL
PUSH AX ; and push it onto word stack
CALL BCD_BINARY ; Do the conversion
POP AX ; Get the binary value
MOV BIN, AL ; and save it
NOP ; Continue with program
; PROCEDURE: BCD_BINARY Converts BCD numbers to binary.
; INPUT : None - BCD value assumed to be on stack before call
; OUTPUT : None - Binary value on top of stack after return
; DESTROYS: Nothing
BCD_BINARY PROC NEAR
PUSHF ; Save flags
PUSH AX; and registers: AX
PUSH BX; BX
PUSH CX; CX
PUSH BP; BP. Why BP?
MOV BP, SP; Make a copy of the
; stack pointer in BP
MOV AX, [BP+ 12]; Get BCD number from
; stack. But why it is on
; BP+12 location? Please note 5 PUSH statements + 1 call which is intra-segment (so
; just IP is stored) so total 6 words are pushed after AX has been pushed and since it is
; a word stack so the BCD value is stored on 6 × 2 = 12 locations under stack. Hence
; [BP + 12] (refer to the figure given on next page).
MOV BL, AL; Save copy of BCD in BL
AND BL, 0Fh; mask lower 4 bits
AND AL, F0H; Separate upper 4 bits
MOV CL, 04; Move upper BCD digit to low
ROR AL, CL; position BCD digit for multiply location
MOV BH, 0Ah ; Load 10 in BH
MUL BH; Multiply upper BCD digit in AL by 10
; The result is in AL
ADD AL, BL; Add lower BCD digit to result.
MOV [BP + 12], AX ; Put binary result on stack
; Restore flags and registers
POP BP
POP CX
POP BX
POP AX
POPF
RET
BCD_BINARY ENDP
CODE_SEG ENDS
END START
Discussion:
The parameter is pushed on stack before the procedure call. Procedure call causes the current instruction pointer to be pushed on to stack. In the procedure flags AX, BX, CX and BP registers are also pushed in that order. Hence the stack looks to be:
The instruction MOV BP, SP transfers contents of the SP to BP register. Now BP is used to access any location in stack by adding appropriate offset to it. For illustration MOV AX, [BP + 12] instruction transfers the word starting at the 12th byte from the top of stack to AX register. It doesn't change the contents of BP register or top of the stack. It copies pushed value of AL and AH at offset 008Eh into the AX register. This instruction isn't equivalent to POP instruction.
Stacks are useful for writing procedures for multi-user system programs or recursive procedures. It's a decent practice to make a stack diagram as above when using procedure call through stacks. This helps in reducing errors in programming.