EET 2261 Unit 6 The Stack; Subroutines Read Almy, Chapter 11. Homework #6 and Lab #6 due next week. Quiz next week. The Stack •The stack is a section of RAM used for temporary storage. •The term “LIFO” (last-in-first-out) is often used to describe the stack. •The last value you put in is the first one you’ll take out, as in a plate dispenser at a salad bar. The Stack Pointer •The programmer gets to decide where in RAM the stack is located. She does this by setting the value in the stack pointer register (SP). •This value is treated as the address of the “top” of the stack. •Usually the address used is the highest RAM address, plus one. For us, that address is $4000. •So in many programs, one of the first instructions will be LDS #$4000. Review: HCS12 Memory Map •See page 26 of Device User Guide. Pushing and Pulling •We use the word “push” for putting values onto the stack, and the word “pull” for retrieving values from the stack. •As we push or pull, the stack pointer (SP) is automatically updated to reflect the fact that the top of the stack has moved: •Each push decrements SP by 1 or 2. •Each pull increments SP by 1 or 2. •See next slide for push and pull instructions. Push Instructions and Pull Instructions (Table from p. 82 of the HCS12 CPU Reference Manual.) Using the Stack: Example •Predict contents after each instruction executes: Instruction A B SP Mem $3FFD Mem. $3FFE Mem. $3FFF LDS #$4000 0 0 $4000 0 0 0 LDAA #$12 $12 0 $4000 0 0 0 PSHA $12 0 $3FFF 0 0 $12 DECA $11 0 $3FFF 0 0 $12 LDAB #$34 $11 $34 $3FFF 0 0 $12 PSHD $11 $34 $3FFD $11 $34 $12 0 0 $3FFD $11 $34 $12 PULD $11 $34 $3FFF $11 $34 $12 PULA $12 $34 $4000 $11 $34 $12 LDD #$00 Other Uses of the Stack •As seen above, the programmer can use the stack by issuing push or pull instructions. •Also, under certain conditions the HCS12 automatically pushes data onto the stack or pulls data off the stack. No push or pull instructions are needed in these cases. •Examples: Subroutines (which we’ll study in a few slides) and interrupts (which we’ll study in a few weeks) are the two most common conditions of this sort. Initializing the Stack Pointer •Since the HCS12 automatically uses the stack under certain conditions, it’s a good idea to initialize the stack pointer (with an LDS instruction) at the beginning of every program, even if you don’t plan to use any push or pull instructions. •Otherwise, the stack could be located anywhere in memory, possibly in an area of memory that overlaps with your program’s code or data. Avoiding Conflicts with the Stack •Be sure to locate the top of the stack far away from the location of your code and data. Otherwise your code and data may be wiped out by stack operations. •If we always start our programs at $2000 and locate the top of the stack at $4000, that leaves plenty of room between our code and the stack. •Question: How many bytes (and kilobytes) are there between addresses $2000 and $4000? Subroutines •A subroutine is a small program that performs some well-defined task within a bigger program. •Why use subroutines? •If you have a block of code that must be executed at different places within your program, make it a subroutine. •Long, complicated programs are easier to understand and maintain if you break the program up into separate chunks (subroutines). Calling a Subroutine • The first instruction in a subroutine has a label, which serves as that subroutine’s name. • You can call a subroutine by name using either of these instructions: • Branch to Subroutine (BSR), which uses relative addressing mode. • Jump to Subroutine (JSR), which uses direct, extended, or indexed addressing mode. Returning from a Subroutine • A subroutine must end with the RTS (Return from Subroutine) instruction, which causes execution of the calling program to resume. Main Program . . . BSR Subby ADDA $1000 Subroutine Subby: LDAB #05 . . . RTS . . . • BSR is similar to BRA, except that it also causes the processor to “remember” where to resume when it hits a RTS. Subroutines and the Stack • How does the HCS12 remember where in the main program to resume when it hits a RTS? • When it executes the BSR instruction, it pushes the Program Counter (which contains the address of the next instruction) onto the stack. • When it hits the RTS, it pulls this address back from the stack into the Program Counter. This lets it pick up where it left off in the main program. No Need For You To Push or Pull • Recall from earlier that the HCS12 has several push and pull instructions (such as PSHA and PULA) that let you place values on the stack or remove them from the stack. • You don’t need to use these instructions when you branch to a subroutine. The HCS12 pushes and pulls the desired values automatically. Jump and Subroutine Instructions (Table from p. 79 of the HCS12 CPU Reference Manual.) • CALL and RTC are advanced instructions that we won’t use. CALL is similar to BSR, and RTC is similar to RTS. Overall Program Structure • Many programs have a general structure that contains three major parts: 1. Initialization code that executes once when the program starts. 2. The program’s main body, which typically is a “forever” loop that starts with a label and ends with a BRA to that label. The main body will often contain one or more BSR instructions that call subroutines. 3. Subroutines, each of which begins with a label and ends with an RTS. Overall Program Structure: Example ABSENTRY Entry ORG $2000 Entry: CLI LDS #$4000 MainLoop: BSR Sub1 BSR Sub2 BRA MainLoop Sub1: Sub2: INCA RTS INCB RTS END Initialization Main body (“forever” loop) Subroutines Troubleshooting Programs with Subroutines Single Step (F11). Steps one instruction at a time. Step Over (F10). For most instructions it’s the same as Single Step, but for BSR it executes the entire subroutine as one step.