Subroutines and Stack Usage on the MicroBlaze ECE 3534 Microprocessor System Design 1
MicroBlaze Subroutines Same idea as a C/C++ function There s no call instruction Instead, branch and link Example: MAIN_PROG:... brlid nop... r15, MY_SUB MY_SUB: <sub. code goes here> rtsd r15, 8 nop 2
MAIN_PROG:... brlid nop... r15, MY_SUB MY_SUB: <sub. code goes here> rtsd r15, 8 nop This puts the address of the brlid instruction into r15. Execution transfers to MY_SUB. This transfers execution to r15 + 8, = the 2 nd instruction after the brlid. A delay instruction allows the instruction following it to execute before the branch is taken 3
Other Branch-Link Flavors To invoke a subroutine: brld rd, rb brald rd, rb brlid rd, IMM braild rd, IMM link : rd PC if (absolute) PC offset else PC PC + offset 4
Issues with Subroutine Linkage The convention is to use R15 as the link register (but this is not dictated by the MB hardware) Now, suppose one subroutine needs to call another... Both subroutines can t use r15, can they? Also, we need a way to pass parameters to subroutines, and to receive values returned from subroutines Suppose we want to support MANY levels of nested subroutine calls... 5
Examples of Stacks Top of stack Bottom of stack 6
Stacks LOW MEM Very common data structure Also called a LIFO (Last-In, First- Out) Terminology: push: place a value on the top of a stack pop: remove a value from the top of a stack SP-> <E M P T Y > Bottom of stack-> HIGH MEM 7
Stacks LOW MEM No dedicated stack mechanism in MicroBlaze Free to invent your own rules My rules: Stack grows down in memory Devote (arbitrarily) R1 as the SP SP points to the top item on the stack SP-> Bottom of stack-> <E M P T Y > HIGH MEM 8
Stacks LOW MEM Conventions / cautions: Access only the top value on a stack, otherwise, be careful Refer to Stack Frames Bottom Beware overflow and underflow of stack-> It is VERY common to use a system stack to support subroutine linkage (it s exactly what is needed to support nested calls/ returns) SP-> <E M P T Y > HIGH MEM 9
Physical Stacks
Stacks on the MicroBlaze No dedicated stack mechanism in MicroBlaze Typical for most RISC machines Just use load/store instructions Need to dedicate a particular register as the Stack Pointer Conventions: Use R1 as the Stack Pointer R1 will normally contain the address of the value at the top of the stack We will cause the stack to grow toward memory address 0 11
Stack Operations in Memory R1 R1 R1 R1
Call / Return brlid rl,imm rtsd rl,imm <------ CALL <------- RETURN
Example Stack Operations.equ TOP_OF_MEMORY, 0x00003ffc # Last addr of on-chip mem INITIALIZE:... addi r1,r0,top_of_memory # Initialize r1 as SP... MY_CODE:... addi r1,r1,-4 # Decrement SP sw r2,r0,r1 # Push r2 onto stack...... lw r2,r0,r1 # Pop value from the stack addi r1,r1,4 # Increment SP... PUSHING: PREDECREMET POPPING: POST- INCREMENT 14
Efficiency When Pushing Lots of Registers MY_CODE:... addi r1,r1,-28 # Adjust stack pointer swi r2,r1,24 # Push r2 onto the stack swi r3,r1,20 # Push r3 onto the stack swi r4,r1,16 # Push r4 onto the stack swi r5,r1,12 # Push r5 onto the stack swi r6,r1,8 # Push r6 onto the stack swi r7,r1,4 # Push r7 onto the stack swi r8,r1,0 # Push r8 onto the stack... 15
Register Usage With Stacks and Subroutines Particular register must be dedicated as the Stack Pointer (convention: R1) MicroBlaze requires a link register for calls/returns (convention: R15) Pass a small number of parameters via registers (R5, etc.) It s common for a subroutine to return a value via a register (R4) Subroutine etiquette: scratchpad registers should be restored to their original values before returning With nested calls, we could quickly run out of registers Solution: temporarily store register values on the system stack 16
Summary Subroutines Modular design Divide and conquer Code re-use A good subroutine is one that does only one thing --- and does it very well. Stacks Fast, simple means of dynamic memory allocation No size limit (in theory) Ideally suited for subroutine linkage 17
Stack Frame High Memory Func 1 Func 1 Func 1 Func 1 SP Func 2 Func 2 Func 2 SP Func 3 SP Low Memory SP X9584 Figure 3-2: Stack Frame Func1 calls Func2, which in turn calls Func3. After the call from Func1 to Func 2, the value of the stack pointer (SP) is decremented. This value of SP is again decremented to accommodate the stack frame for Func3. On return from Func3 the value of the stack pointer is increased to its original value in the function, Func 2.
Stack Frame Figure 3-1: Stack Convention High Address Function Parameters for called sub-routine (Arg n..arg1) (Optional: Maximum number of arguments required for any called procedure from the current procedure.) Old Stack Pointer Link Register (R15) Callee Saved Register (R31...R19) (Optional: Only those registers which are used by the current procedure are saved) Local Variables for Current Procedure (Optional: Present only if Locals defined in the Figure procedure) 3-1: Stack Convention Functional Parameters (Arg n.. Arg 1) (Optional: Maximum number of arguments required for any called procedure from the current procedure) New Stack Pointer Link Register Low Address