1 / 10

Chapters 9 & 10

Chapters 9 & 10. Midterm next Wednesday (11/19) Trap Routines & RET Subroutines (or Functions) & JSR & JSRR & RET The Stack SSP & USP Interrupts RTI. Traps. Execute TRAP “vector” - Service Routine Addresses

gitel
Download Presentation

Chapters 9 & 10

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapters 9 & 10 • Midterm next Wednesday (11/19) • Trap Routines • & RET • Subroutines (or Functions) • & JSR & JSRR • & RET • The Stack • SSP & USP • Interrupts • RTI

  2. Traps • Execute TRAP “vector” - Service Routine Addresses Trap Vectors are at memory locations [0000:00FF] Trap Vectors contain addresses of “Pre written (?)” Service Routines 2) [PC] is stored in R7 3) Address of Trap Service Routine loaded into PC 4) Service Routine Program executed • Trap service routine program ends with an RET ([R7] loaded into PC)

  3. Subroutines 1) Execute JSR or JSRR - Call Subroutine or Method Location of Subroutine is specified in the Instruction 2) [PC] stored in R7 3) Address from JSR or JSRR is loaded into PC 4) Subroutine is executed R0 likely contains passed parameter (or address) R5 may be used to return error message R0 likely contains return parameter (or address) 5) Subroutine program ends with an RET ( [R7] loaded into PC) How does this mechanism support recursion?

  4. The STACK • The Stack is a dynamic “data structure” descending from high memory to lower memory (The stack grows down ) • The Stack Pointer (R6) points to the top word on the stack. (The Stk Ptr is the “stack reference” that is available to the programmer) • A new entry (word) is “PUSHed” onto the stack • To take a word off of the Stack, the top word is “POPed” off of the stack.

  5. Stack R6 is the Stack Ptr Push: Push ADD R6, R6, #-1 ; Decrement Stack Ptr STR R0, R6, #0 ; “Push” Data onto Stack Pop: Pop LDR R0, R6, #0 ; “Pop” Data off of Stack ADD R6, R6, #1 ; Increment Stack Ptr Which way does the Stack grow? Where does Stack Ptr (R6) point?

  6. Stack Underflow Check (Stack Empty) ; Stack POP subroutine. SP is R6. Returns “data” in R0. ; Fails if the stack is empty (SP=x4000) and reports error (1 --> R5) POP LD R1, STK_Empty ; Compare Stk Ptr with “Empty” ADD R2, R6, R1 BRz fail_exit ; EXIT IF STACK IS EMPTY ; if ok, Pop LDR R0, R6, #0 ; Pop top of Stack into R0 and ADD R6, R6, #1 ; Increment Stk Ptr AND R5, R5, #0 ; R5 <-- 0 (POP successful) RET fail_exit AND R5, R5, #0 ; R5 <-- 1 (POP failed - underflow) ADD R5, R5, #1 RET STK_Empty .FILL xC000 ; STK_Empty  -x4000 (Stack begins at x3FFF)

  7. Stack Overflow Check (Stack too Large) ; Stack PUSH subroutine. SP is R6. Value in R0 is pushed onto the stack. ; Fails if Stack is full (SP=x3F00) and reports error (1  R5) PUSH LD R1, STK_Full ; Compare Stack Ptr with “Full” ADD R2, R6, R1 BRz fail_exit ; EXIT IF STACK IS FULL ; if ok, PUSH ADD R6, R6, #-1 ; Decrement Stk Ptr and STR R0, R6, #0 ; “Push” R0 onto top of Stack AND R5, R5, #0 ; “Report” no Error 0  R5 RET fail_exit AND R5, R5, #0 ; “Report Error” 1  R5 ADD R5, R5, #1 RET STK_Full .FILL xC100 ; STK_Full <-- -x3F00 (Stack max is x3F00)

  8. Subroutine for Push & Pop ; PUSH and POP Subroutines. STK Ptr is R6. Data in R0. Success: R0 = 0. ; Stack: x3FFF to x3F00 (256 words max). POP and PUSH are Entry Points. POP ST R2,Save2 ; R1 & R2 are used by “POP”. Save them. ST R1,Save1 LD R1,STK_Empty ; Compare Stk Ptr with “Empty” ADD R2,R6,R1 BRz fail_exit ; EXIT IF STACK IS EMPTY LDR R0,R6,#0 ; “POP” top of Stack into R0 and ADD R6,R6,#1 ; Increment stack pointer BRnzp success_exit PUSH ST R2,Save2 ; R1 & R2 are used by “PUSH”. Save them. ST R1,Save1 LD R1,STK_Full ; Compare Stk Ptr with “Full” ADD R2,R6,R1 BRz fail_exit ; EXIT IF STACK IS FULL ADD R6,R6,#-1 ; Decrement Stk Ptr and STR R0,R6,#0 ; “PUSH” R0 onto top of Stack success_exit AND R5,R5,#0 ; R5 <-- 0 (success) LD R1,Save1 ; Restore registers and Return LD R2,Save2 RET fail_exit AND R5,R5,#0 ; R5 <-- 1 (failure) ADD R5,R5,#1 LD R1,Save1 ; Restore registers and Return LD R2,Save2 RET STK_Empty .FILL xC000 ; BASE = –x4000. STK_Full .FILL xC100 ; Stack 256 words Save1 .FILL x0000 Save2 .FILL x0000 .END Two Entry Points: JSR POP & JSR PUSH Both [PC]  R7 Two exit Points: RET Both [R7]  PC Has an Initial Stk Ptr Address Here it is x4000 Has a Stack Limit (Often not spec) Here it is 256 words (x100) What is a reasonable length for the Stack ?

  9. Subroutine Using Stack ; Using Stack to store Registers and to pass arguments to Subroutine .ORIG x3000 MAIN ST R6,SaveR6 ; Initialize Stk Ptr (After saving old Stk Ptr) LD R6,STK_Init ADD R6,R6,#-1 ; Push R7 & R0 STR R7,R6,#0 ADD R6,R6,#-1 STR R0,R6,#0 AND R0,R0,#0 ; Push #5 (argument) onto Stack and call Double ADD R0,R0,#5 ADD R6,R6,#-1 ; (Push R0) STR R0,R6,#0 JSR Double LDR R0,R6,#0 ; Pop R0 ** Returned Value from Double ** ADD R6,R6,#1 LDR R0,R6,#0 ; Pop R0 & R7 ADD R6,R6,#1 LDR R7,R6,#0 ADD R6,R6,#1 LD R6,SaveR6 ; Restore old Stk Ptr Loop BRnzp Loop ; Loop when DONE SaveR6 .BLKW 1 STK_Init .FILL x4000 ; Subroutine ; Double value passed and returned on Stack Double LDR R0,R6,#0 ; Pop argument from Stack ADD R6,R6,#1 ADD R0,R0,R0 ; Multiply R0 by 2 ADD R6,R6,#-1 ; Push return argument on Stack STR R0,R6,#0 RET .END Has an Initial Stk Ptr x4000 Registers Stored on Stack Pushed in beginning Poped at end Arguments Passed on Stack Pushed by MAIN Poped by Double Pushed by Double Poped by MAIN What are challenges using the stack this way ? What are the benefits ?

  10. Recursive Subroutine ; Using the Stack for Recursive Subroutine Calls MAIN ST R0, SaveR0 ; Save Registers Used ST R1, SaveR1 ST R6, SaveR6 ST R7, SaveR7 LD R6, STK_Init ; Initialize STK_Ptr (R6) AND R1, R1, #0 ; R1 <-- 10 (Depth of Recursion) ADD R1, R1, #10 JSR SUBR ; Call SUBR LD R0, SaveR0 ; Restore Registers LD R1, SaveR1 LD R6, SaveR6 LD R7, SaveR7 Loop BRnzp Loop ; Loop when done SaveR0 .BLKW 1 SaveR1 .BLKW 1 SaveR6 .BLKW 1 SaveR7 .BLKW 1 STK_Init .FILL x4000 ; Recursive Subroutine (Stores R7 on the Stack) ; R1 is "shared" by all instances of SUBR SUBR ADD R0, R7, #0 ; Push R7 onto Stack JSR PUSH ADD R1, R1, #-1 ; Decrement R1 BRz done JSR SUBR ; Call SUBR again done JSR POP ; Pop R7 from Stack ADD R7, R0, #0 RET Are the PC and R7 the same ? Are the STK Ptr and R6 the Same ? Could we have stored R0 – R7 on Stack ? Why didn’t we store R0 & R1 in SUBR ? Could we have used SaveR0 & Save R1 in SUBR to save R0 & R1 ? How can we change this for SUBR to call itself until the Stack is full, and then terminate (unwind) properly ?

More Related