Subroutines: Passing Arguments Using the Stack

21
Subroutines: Passing Arguments Using the Stack

description

Subroutines: Passing Arguments Using the Stack. Passing Arguments via the Stack. Arguments to a subroutine are pushed onto the stack. The subroutine accesses the arguments from the stack using the Base Pointer (BP) and indirect addressing. - PowerPoint PPT Presentation

Transcript of Subroutines: Passing Arguments Using the Stack

Page 1: Subroutines: Passing Arguments Using the Stack

Subroutines: Passing Arguments Using the Stack

Page 2: Subroutines: Passing Arguments Using the Stack

Passing Arguments via the Stack

Arguments to a subroutine are pushed onto the stack.

The subroutine accesses the arguments from the stack using the Base Pointer (BP) and indirect addressing.

Arguments can be passed by value (their values are pushed onto the stack, or by reference (their offsets are pushed onto the stack).

Page 3: Subroutines: Passing Arguments Using the Stack

The calling routine used in MAIN3 can be either:

To use CALL by Value: PUSH X PUSH Y CALL SUB1

To use CALL by Reference: PUSH OFFSET X PUSH OFFSET Y CALL SUB1

Page 4: Subroutines: Passing Arguments Using the Stack

Call by Value Using the Stack

Suppose that X and Y are defined in the MAIN file:

    X DW ...    Y DW ...

To call a subroutine CALC to evaluate X - 2Y using call by value:

Page 5: Subroutines: Passing Arguments Using the Stack

TITLE MAIN3 (main3.asm) EXTRN CALC: NEAR .MODEL SMALL .STACK 100H .DATA X DW 30 Y DW 40 .CODE MAIN3 PROC     MOV AX, @DATA     MOV DS, AX PUSH Y ; call by value PUSH X CALL CALC ; the answer should be returned in AX MOV AX,4C00H     INT 21H MAIN3 ENDP     END MAIN3

Page 6: Subroutines: Passing Arguments Using the Stack

Call by Value Using the Stack(Cont.)

TITLE CALC (CALC.ASM - a separate file) PUBLIC CALC .MODEL SMALL .CODE CALC PROC NEAR ;evaluates X - 2Y with result in AX PUSH BP          ;save BP (and DEC SP)     MOV BP,SP        ;BP pts to stack top ; push any registers to be used in the subroutine and ; restored before returning from the subroutine here     MOV AX,[BP+4]   ;AX has X     SUB AX,[BP+6]   ;AX = X - Y SUB AX,[BP+6] ;AX = X - 2Y ; pop any registers that were saved in the subroutine here     POP BP          ;restore BP     RET 4           ;pop IP and add 4 bytes to SP CALC ENDP     END

Page 7: Subroutines: Passing Arguments Using the Stack

Call by Value Using the Stack(Cont.)

Stack Representation for NEAR Call by Value in this version of the program:

Instruction      Stack Contents     SP          BP (at the end of this code)

PUSH Y (Arg1)   Y SP -=2     [BP+6] = offset of Y on stack PUSH X (Arg2)   X               SP -=2     [BP+4] = offset of X on stackCALL CALC        Ret Address         SP -=2     [BP+2] = RETADDR (IP)PUSH BP          BP                 SP -=2     [BP] = original contents of BPMOV BP, SP BP = SPpush regs regs SP -=2/each

Page 8: Subroutines: Passing Arguments Using the Stack

Call by Value Using the Stack(Cont.)

The purpose of using the BP in this way is because it gives a standard way to retrieve arguments from the stack that is not affected by pushing any additional registers or other values within the subroutine.

Note: if BP is used for indirect addressing, it is assumed to be referring to an offset in the stack segment (SS). Any other register used for indirect addressing is assumed to be an offset in the data segment (DS).

Page 9: Subroutines: Passing Arguments Using the Stack

TITLE CALC (CALC.ASM - a separate file) PUBLIC CALC .MODEL SMALL .CODE CALC PROC NEAR ;evaluates X - 2Y with result in AX PUSH BP          ;save BP     MOV BP,SP        ;BP points to stack top ; push any registers to be used in the subroutine     MOV AX, [BP+4]   ;AX has X     SUB AX, [BP+6]   ;AX = X - Y SUB AX, [BP+6] ;AX = X - 2Y ; pop any registers that were saved in the subroutine     POP BP          ;restore BP     RET 4           ;pop IP and add 4 bytes to SP CALC ENDP     END

Page 10: Subroutines: Passing Arguments Using the Stack

NOTEC assumes that (1) the calling program will fix the stack after the return from a subroutine (2) arguments will be passed using call by value (3) arguments are pushed in reverse order, as shown above.

Different compilers use different calling conventions.

Page 11: Subroutines: Passing Arguments Using the Stack

FIXING UP THE STACKIf the subroutine is to fix up the stack,

then it should end up with: RET 2*no. of arguments

e.g. if there are 3 arguments, then it should end up with: RET 6

If the calling program is to fix up the stack, then the subroutine should end up with: RETand, assuming that the subroutine is SUB1, the calling program should contain the code: call sub1 add sp, 6 (i.e. 2*no. of arguments)

Page 12: Subroutines: Passing Arguments Using the Stack

ILLUSTRATION OF A RECURSIVE PROCEDURE

A procedure to evaluate factorial(n)

if n = 1 return 1else return n*factorial(n-1)

Page 13: Subroutines: Passing Arguments Using the Stack

factorial proc nearpush bpmov bp,spcmp word ptr [bp+4], 1jg contmov ax, 1jmp endup

cont: mov bx, [bp+4]dec bxpush bxcall factorial

Page 14: Subroutines: Passing Arguments Using the Stack

imulword ptr [bp+4]endup:

pop bpret 2

factorial endpend

Page 15: Subroutines: Passing Arguments Using the Stack

An Example of a Recursive Procedure

Employed in Cryptography

Definition. The GCD (greatest common denominator) of two numbers a, b is the largest number that divides both a and b.  

15

Page 16: Subroutines: Passing Arguments Using the Stack

  Euler’s Extended Algorithm. For given a, b to find: (a) the GCD d of a, b(b) numbers x and y (positive, negative or zero) such that xa + yb = d(Euler’s original algorithm is just part (a) )

16

Page 17: Subroutines: Passing Arguments Using the Stack

Define E(a,b) as a function whose value is the triple (x, y, d) such that d is the GCD of a, b and xa + yb = d. E(a,b) can then be evaluated using the following recursive algorithm:Function E(a, b) where a > b If b = 0 then return (1, 0, a), else evaluate q, r such that a = qb + r and 0 ≤ r < b. Evaluate E(b, r), let result be (X, Y, D) Return (Y, X – qY, D)End function

17

Page 18: Subroutines: Passing Arguments Using the Stack

EXAMPLE. To find the GCD d of 75 and 30, and, further to find x, y such that 75x + 30y = d.E(75, 30) = (x1, y1, d) to be filled in later

75 = 2*30 + 15 (so q1 = 2)

E(30, 15) = (x2, y2, d) to be filled in later

30 = 2*15 + 0 (so q2 = 2)

E(15, 0) = (x3, y3, d) = (1, 0, 15). So d = 15.

Now x2 =y3=0 and y2 = x3 – q2y3 = 1

and x1 =y2=1 and y1 = x2 – q1y2 = -2

So d = 15 and 1*75 + (-2)*30 = 15

18

Page 19: Subroutines: Passing Arguments Using the Stack

Proof that the algorithm works (optional) The case where b = 0 obviously returns the correct result, since 1*a + 0*0 = a, and a is the GCD of a and 0.

If b > 0, and q, r, X, Y, D are as defined in the algorithm, then Xb + Yr = D where D is the GCD of b,rSince r = a - qb, this provides Xb + Y(a-qb) = DGiving Ya + (X-qY)b = D

19

Page 20: Subroutines: Passing Arguments Using the Stack

The previous slide showed showed that if x, y are evaluated as in the algorithm, then xa + yb = DBut is D the gcd of a,b ? By defn. D | b and D | r.So since a = qb + r, we get D | a.Let d be any no. that divides both a and b.Then since r = a - qb, it follows that d | r.We now have d | b and d | r. So by defn. d D. It follows that D is the GCD of a,b.

20

Page 21: Subroutines: Passing Arguments Using the Stack

Finally note that the algorithm terminates, because each recursive call involves nonnegative arguments whose sum is less than that of the previous iteration. So the sequence of iterations must end up with one in which the smaller second argument is zero

21