Download presentation

Presentation is loading. Please wait.

Published byMireya Deas Modified about 1 year ago

1
Computer Science 210 Computer Organization Recursive Subroutines System Stack Management

2
Saving and Restoring Registers Generally use “callee-save” strategy, except for return values. –Save anything that the subroutine will alter internally that shouldn’t be visible when the subroutine returns. –It’s good practice to restore incoming arguments to their original values (unless overwritten by return value). Remember: You MUST save R7 if you call any other subroutine or TRAP.

3
;; Author: Ken Lambert ;; Calls the subroutine ORDER to guarantee that FIRST <= SECOND.ORIG x3000 ;; Main program register usage: ; R1 = initial value of FIRST ; R2 = initial value of SECOND ; Main program code LD R1, FIRST LD R2, SECOND JSR ORDER ST R1, FIRST ST R2, SECOND HALT ; Main program data FIRST.BLKW 1 SECOND.BLKW 1 ;; Subroutine ORDER ; Guarantees that R1 <= R2 ; Input parameters: R1 and R2 ; Output parameters: R1 and R2 ; R3 = temporary working storage ORDERST R3, ORDERR3; Save R3 JSR SUB BRnz ENDORD; Exit if difference <= 0 ADD R3, R2, #0; Swap values in R1 and R2 ADDR2, R1, #0 ADD R1, R3, #0 ENDORDLD R3, ORDERR3; Restore R3 RET ; Data variable for subroutine ORDER ORDERR3.BLKW 1 ;; Subroutine SUB... Example: ORDER makes R1 <= R2 Is there a bug here?

4
;; Author: Ken Lambert ;; Calls the subroutine ORDER to guarantee that FIRST <= SECOND.ORIG x3000 ;; Main program register usage: ; R1 = initial value of FIRST ; R2 = initial value of SECOND ; Main program code LD R1, FIRST LD R2, SECOND JSR ORDER ST R1, FIRST ST R2, SECOND HALT ; Main program data FIRST.BLKW 1 SECOND.BLKW 1 ;; Subroutine ORDER ; Guarantees that R1 <= R2 ; Input parameters: R1 and R2 ; Output parameters: R1 and R2 ; R3 = temporary working storage ORDERST R3, ORDERR3; Save R3 STR7, ORDERR7 ; Save R7 JSR SUB BRnz ENDORD; Exit if difference <= 0 ADD R3, R2, #0; Swap values in R1 and R2 ADDR2, R1, #0 ADD R1, R3, #0 ENDORDLD R3, ORDERR3; Restore R3 LDR7, ORDERR7 ; Restore R7 RET ; Data variables for subroutine ORDER ORDERR3.BLKW 1 ORDERR7.BLKW 1 ;; Subroutine SUB... Example: ORDER makes R1 <= R2 Back up ret address before another call

5
def factorial(n): if n == 0: return 1 else: return n * factorial(n - 1) Iteration vs Recursion def factorial(n): product = 1 while n > 0: product *= n n -= 1 return product Including 0 in the domain makes the assembler version easier

6
; Main program code LD R1, NUMBER JSR FACTORIAL ST R2, NUMBER HALT ; Main program data variables NUMBER.BLKW 1 ;; Subroutine FACTORIAL ; Returns the factorial of R1 in R2 ; Input parameter: R1 (the number) ; Output parameter: R2 (the product) ; R3 = temporary working storage ;; Pseudocode: ; product = 1 ; while number > 0 ; product *= number ; number -= 1 FACTORIALST R7, FACTTEMPR7; Save my return address ST R3, FACTTEMPR3; Save the working storage ST R1, FACTTEMPR1; Save my input parameter LD R2, FACTONE; Initialize the product to 1 WHILEJSR MUL; R3 = R1 * R2 ADDR2, R3, #0; Shift the product back to R2 ADD R1, R1, #-1; Decrement the number BRp WHILE LD R1, FACTTEMPR1; Restore my input parameter LD R3, FACTTEMPR3; Restore the working storage LD R7, FACTTEMPR7; Restore my return address RET ; Data for subroutine FACT FACTONE.FILL 1 FACTTEMPR1.BLKW 1 FACTTEMPR3.BLKW 1 FACTTEMPR7.BLKW 1 Iterative factorial routine in assembler

7
; Main program code LD R1, NUMBER JSR FACTORIAL ST R2, NUMBER HALT ; Main program data variables NUMBER.BLKW 1 ;; Subroutine FACTORIAL ; Returns the factorial of R1 in R2 ; Input parameter: R1 ; Output parameter: R2 ; R3 = temporary working storage ;; Pseudocode: ; if number > 0 ; return number * fact(number – 1) ; else ; return 1 FACTORIALADD R1, R1, #0; If number > 0 then recurse BRp RECURSE LD R2, FACTONE; Base case: return 1 RET RECURSEST R7, FACTTEMPR7; Save my return address ST R3, FACTTEMPR3; Save the working storage ST R1, FACTTEMPR1; Save my input parameter ADD R1, R1, #-1; Decrement the number JSR FACTORIAL LD R1, FACTTEMPR1; Restore my input parameter JSR MUL; R3 = R1 * R2 [number * fact(number – 1)] ADD R2, R3, #0; Shift the product back to R2 LD R3, FACTTEMPR3; Restore the working storage LD R7, FACTTEMPR7; Restore my return address RET ; Data for subroutine FACT FACTONE.FILL 1 FACTTEMPR1.BLKW 1 FACTTEMPR3.BLKW 1 FACTTEMPR7.BLKW 1 Recursive factorial routine in assembler

8
Problem Each call of the subroutine overwrites R7 with its return address, but all of the calls save R7 in the same data variable Each call must return to a context in which its own parameter R1 was saved, but they’re all saved in the same data variable Restoration of registers for more than one recursive call is impossible

9
Solution We need a means of stacking up saved values so the contexts of calls can be saved and restored in a last in, first out manner (many instances of R1, R7, etc.) A system stack provides for this

10
The Stack Interface The stack structure consists of a stack pointer (in R6, which now can’t be used for anything else) and two subroutines, PUSH and POP At program startup, the stack pointer is initialized to an address just above the keyboard status register R0 provides the interface for data pushed or popped

11
The Stack Implementation The stack pointer moves up (to a smaller memory address) during a PUSH The stack pointer moves down (to a larger memory address) during a POP Won’t bother with stack overflow or underflow for now

12
The Place of the Runtime Stack in Memory System memory Main program (code and data) Subroutines (code and data) Runtime System Device registers STACK BOTTOM: xFDFF Each push decrements the stack pointer by one Stack grows upwards toward user memory Main program.ORIG: x3000 System.ORIG: x0000

13
; Main program code LD R6, STACKBOTTOM; Initialize the stack pointer LD R1, NUMBER JSR FACT ST R2, NUMBER HALT ; Main program data variables STACKBOTTOM.FILL xFDFF; Address of the bottom of the stack NUMBER.BLKW 1 ;; Subroutine PUSH ; Copies R0 to the top of the stack and decrements the stack pointer ; Input parameters: R0 (the datum) and R6 (the stack pointer) ; Output parameter: R6 (the stack pointer) PUSHADD R6, R6, #-1 STR R0, R6, #0 RET ;; Subroutine POP ; Copies the top of the stack to R0 and increments the stack pointer ; Input parameter: R6 (the stack pointer) ; Output parameters: R0 (the datum) R6 (the stack pointer) POPLDR R0, R6, #0 ADD R6, R6, #1 RET Defining the Stack Resource

14
;; Subroutine FACTORIAL ; Returns the factorial of R1 in R2 ; Input parameter: R1 ; Output parameter: R2 ; R3 = temporary working storage ;; Pseudocode: ; if number > 0 ; return number * fact(number – 1) ; else ; return 1 FACTORIALADD R1, R1, #0; If number > 0 then recurse BRp RECURSE LD R2, FACTONE; Base case: return 1 RET RECURSEADD R0, R7, #0; Save my return address JSR PUSH ADD R0, R3, #0; Save the working storage JSR PUSH ADD R0, R1, #0; Save my input parameter JSR PUSH ADD R1, R1, #-1; Decrement the number JSR FACTORIAL JSR POP; Restore my input parameter ADD R1, R0, #0 JSR MUL; R3 = R1 * R2 [number * fact(number – 1)] ADD R2, R3, #0; Shift the product back to R2 JSR POP; Restore the working storage ADDR3, R0, #0 JSR POP; Restore my return address ADD R7, R0, #0 RET ; Data for subroutine FACT FACTONE.FILL 1 Recursive factorial routine in assembler

15
Using the Stack The stack can eliminate the need for declaring subroutine data variables in many cases For example, any routine that calls another one must save and restore R7 Stack ‘em up!

16
Costs and Benefits Using a stack incurs the cost of extra subroutine calls for PUSH and POP A large chunk of memory might go to waste Subroutines in early languages like FORTRAN, with no recursion, could be completely static (no extra overhead for subroutine calls)

Similar presentations

© 2017 SlidePlayer.com Inc.

All rights reserved.

Ads by Google