Presentation is loading. Please wait.

Presentation is loading. Please wait.

Computer Science 210 Computer Organization

Similar presentations


Presentation on theme: "Computer Science 210 Computer Organization"— Presentation transcript:

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 Example: ORDER makes R1 <= R2 Is there a bug here?
;; 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 ORDER ST R3, ORDERR3 ; Save R3 JSR SUB BRnz ENDORD ; Exit if difference <= 0 ADD R3, R2, #0 ; Swap values in R1 and R2 ADD R2, R1, #0 ADD R1, R3, #0 ENDORD LD 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 Example: ORDER makes R1 <= R2 Back up ret address
;; 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 ORDER ST R3, ORDERR3 ; Save R3 ST R7, ORDERR7 ; Save R7 JSR SUB BRnz ENDORD ; Exit if difference <= 0 ADD R3, R2, #0 ; Swap values in R1 and R2 ADD R2, R1, #0 ADD R1, R3, #0 ENDORD LD R3, ORDERR3 ; Restore R3 LD R7, 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 Iteration vs Recursion
def factorial(n): product = 1 while n > 0: product *= n n -= 1 return product def factorial(n): if n == 0: return 1 else: return n * factorial(n - 1) Including 0 in the domain makes the assembler version easier

6 Iterative factorial routine in assembler
; 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 FACTORIAL ST 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 WHILE JSR MUL ; R3 = R1 * R2 ADD R2, 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 Recursive factorial routine in assembler
; 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 FACTORIAL ADD R1, R1, #0 ; If number > 0 then recurse BRp RECURSE LD R2, FACTONE ; Base case: return 1 RET RECURSE ST 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 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 ; 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 Example: factorial(4) n Activation record for factorial(4)
def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1) n 4 Activation record for factorial(4) return value

11 Activations Are Added Dynamically
def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1) n 3 Activation record for factorial(3) return value n 4 Activation record for factorial(4) return value

12 Number of Activations = # Calls
def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1) n 2 Activation record for factorial(2) return value n 3 Activation record for factorial(3) return value n 4 Activation record for factorial(4) return value

13 Recursive Process Bottoms out
def factorial(n): if n == 1: return 1 n 1 Activation record for factorial(1) return value n 2 Activation record for factorial(2) return value n 3 Activation record for factorial(3) return value n 4 Activation record for factorial(4) return value

14 Recursive Process Unwinds
def factorial(n): if n == 1: return 1 n 1 Activation record for factorial(1) return value 1 n 2 Activation record for factorial(2) return value n 3 Activation record for factorial(3) return value n 4 Activation record for factorial(4) return value

15 Activations Are Deallocated
def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1) n 2 Activation record for factorial(2) return value 2 n 3 Activation record for factorial(3) return value n 4 Activation record for factorial(4) return value

16 Activations Are Deallocated
def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1) n 3 Activation record for factorial(3) return value 6 n 4 Activation record for factorial(4) return value

17 Value Returned Is in the First Activation
def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1) n 4 Activation record for factorial(4) return value 24

18 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

19 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

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

21 Defining the Stack Resource
; 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) PUSH ADD 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) POP LDR R0, R6, #0 ADD R6, R6, #1

22 Recursive factorial routine in assembler
;; 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 FACTORIAL ADD R1, R1, #0 ; If number > 0 then recurse BRp RECURSE LD R2, FACTONE ; Base case: return 1 RET RECURSE ADD R0, R7, #0 ; Save my return address JSR PUSH ADD R0, R3, #0 ; Save the working storage ADD R0, R1, #0 ; Save my input parameter 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 ADD R3, R0, #0 JSR POP ; Restore my return address ADD R7, R0, #0 ; Data for subroutine FACT FACTONE .FILL 1

23 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!

24 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)

25 For Friday Type Conversions


Download ppt "Computer Science 210 Computer Organization"

Similar presentations


Ads by Google