Chapter 7
Stack and Subroutines
  Updated: 3/23/15
Basic Idea
 l  Large   programs are hard to handle
   l  We can break them to smaller programs
   l  They are called subroutines
 l  Subroutines   are called from the main
     program
 l  Writing subroutines
   l  When should we jump? (use CALL)
   l  Where do we return to? (use RETURN)
Subroutine
 l    A subroutine is a block of code that is called from different
       places from within a main program or other subroutines.
 l    Saves code space in that the subroutine code does not have to
       be repeated in the program areas that need it;
       l    Only the code for the subroutine call is repeated.
 l    A subroutine can have
       l    parameters that control its operation
       l    local variables for computation.
 l    A subroutine may pass a return value back to the caller.
 l    Space in data memory must be reserved for parameters, local
       variables, and the return value.
Subroutine
Using Subroutines
 l  Whenusing subroutines we need to
   know the following:
   l  Where is the NEXT instruction’s address
   l  How to remember the RETURN address
 l  Subroutines are based on MPU
   instructions and use STACK
Stack
l  Temporary memory
    storage space used                      STKPTR
    during the execution of a
    program
l  Used by MPU
l  Stack Pointer (SP)                       PC
      l    The MPU uses a register
            called the stack pointer,
            similar to the program
            counter (PC), to keep track
            of available stack locations.
Data Storage via the Stack
 l    The word ‘stack’ is used because storage/retrieval of
       words in the stack memory area is the same as
       accessing items from a stack of items.
 l    Visualize a stack of boxes. To build a stack, you place
       box A, then box B, then box C
       l    Notice that you only have access to the last item placed on the stack (the Top
             of Stack –TOS). You retrieve the boxes from the stack in reverse order (C
             then B then A). A stack is also called a LIFO (last-in-first-out) buffer (similar to
             a Queue)
PIC18 Microcontroller Stack
                                                        Content:
 l    Consists of 31 registers-21-                     TOSU/H/L
       bit wide, called the hardware
       stack                                   21-bit
                                                         Address:
                                                         STKPTR
       l    Starting with 1 to 31                        (5-bit)
       l    Stack is neither a part of
             program memory or data
             registers.
       l    To identify these 31 registers,
             5-bit address is needed
       l    PIC18 uses one of the special
             function registers called
             STKPTR (Stack Pointer) to
             keep track of the available
             stack locations (registers).
STKPTR (Stack Pointer) Register
 l    SP4-SP0: Stack Address
 l    STKOF: Stack overflow
       l    When the user attempts to use more than 31 registers to
             store information (data bytes) on the stack, BIT7 in the
             STKPTR register is set to indicate an overflow.
 l    STKUNF: Stack underflow
       l    When the user attempts to retrieve more information than
             what is stored previously on the stack, BIT6 in the
             STKPTR register is set to indicate an underflow.
Instructions to Store and Retrieve
Information from the Stack
 l    PUSH
       l    Increment the memory address in the stack pointer (by
             one) and stores the contents of the counter (PC+2) on the
             top of the stack
 l    POP
       l    Discards the address of the top of the stack and
             decrement the stack pointer by one
 l    The contents of the stack (21-bit address), pointed
       by the stack pointer, are copied into three special
       function registers
       l    TOSU (Top-of-Stack Upper), TOSH (High), and TOSL (Low)
                          TOSU         TOSH         TOSL
Instructions to Store and Retrieve Information
from the Stack
 l    The PIC18 stack has limited capability
       compared to other µPs. It resides within its
       memory, and is limited to 31 locations.
 l    For a CALL, address of next instruction
       (nPC) is pushed onto the stack              0: left alone!
        l    A push means to increment STKPTR, then
              store nPC (Next PC or PC+2) at location
              [STKPTR].
        l STKPTR++; [STKPTR] ←nPC
 l    A return instruction pops the PC off the
       stack.
        l    A pop means read [STKPTR] and store to the
              PC, then decrement
        l    STKPTR (PC ←[STKPTR], STKPTR--)
Example
 l  What
       is the value of PC, TOSU/H/L and
   STKPTR as you execute each line?
 nPC   TOS   STKPTR   W
 22    0     0        00
 24    0     0        20
 26    26    1        20
 28    28    2        20
 2A    26    1        20
 2C    0     0        20
Subroutine Call
 l  In the PIC18F, the stack is used to store the
     return address of a subroutine call.
 l  The return address is the place in the calling
     program that is returned to when subroutine
     exits.
 l  On the PIC18Fxx, the return address is PC+4,
     if PC is the location of the call instruction.
 l  The return address is PC+2 if it is a rcall
     instruction.
Call and Return Instructions (1 of 3)
  l    CALL Label, S (0/1)                                ;Call subroutine
                                   Remember: CALL is
                                   a 2-word Instruction!
                                                           ; located at Label
  l    CALL Label, FAST                                   ;FAST is equivalent to
                                                           ;S=1
        l    If S = 0: Increment the stack pointer and store the contents
              of the program counter (PC+4) on the top of the stack (TOS)
              and branch to the subroutine address located at Label.
        l    If S = 1: Increment the stack pointer and store the contents of
              the program counter (PC+4) on the top of the stack (TOS) and
              the contents of W, STATUS, and BSR registers in their
              respective shadow registers, and branch to the subroutine
              address located at Label.
RETURN
 l  RETURN,0 à gets the address from TOS and
     moves it to PC, decrements stack pointer
 l  RETURN,1 à gets the address from TOS and
     moves it to PC, decrements stack pointer;
     retrieves all shadow registers (WREG,
     STATUS, BSR)*
 l  RETLW         à gets the address from TOS and
     moves it to PC ; returns literal to WREG,
     decrements stack pointer
                                    * 1 or FAST
Call and Return Instructions (2 of 3)
l  RCALL,   n    ;Relative call to subroutine
    within n = ± 512       ;words (or ± 1 Kbyte)
    ;Increments the stack pointer and stores the
    contents of the program counter (PC+2) on
    the top of the stack (TOS) and branch to the
    location Label within n = ± 512 words (or ±
    1 ;Kbyte)
Example
  l    Program Listing with Memory Addresses
                                                        Org 0x40
                2-Word Instructions
                                      END ;will be at the end of the program!
                After CALL:             After RETURN:
Note:
2-Word          TOS=00 00 2E
àInst.         PC=00 00 40             PC=2E
PC+4 (2Aà2E)
                STKPTR=01               STKPTR=00
Subroutine Architecture
  How do we write a subroutine?
                            Parameter Passing
          Inputs          Basic Functionality
                                                   Outputs
                         Register Modifications
                        List of Subroutines used
Macros and Software Stack
 l    Macro
       l    Group of assembly language instructions that can be
             labeled with name
       l    Short cut provided by assembler
       l    Format includes three parts
 Push_macro                 macro           arg
                            movff           arg,POSTINC1
                            endm
 USE:                       Push_macro              WREG
                                   A push means to increment STKPTR,
                                   then store nPC (Next PC or PC+2) at
                                   location [STKPTR].
                                        STKPTR++; [STKPTR] ←nPC
Macro Description - Example
 l  See how FSR is loaded and POSTDEC works.
 l  How a MACRO is being called!
            Before MAIN
MACRO Application
 l    Note COUNT is not defined in the MARCO
       l    It is the "arg” of the MACRO
 l    MACRO is assembled after every instance it is called
MACRO Application
 l    So what if MACRO is called multiple times?
       l    A MACRO is assembled after every instance it is
             called
Subroutine versus Macro
 l    Subroutine (by MPU)           l    Macro (by assembler)
       l  Requires instructions           l  Based on assembler
           such as CALL and
                                           l  Shortcut in writing
           RETURN, and the
           STACK (overhead)                    assembly code
       l  Memory space required           l  Memory space
           by a subroutine does                required depends on
           not depend on how                   how many times it is
           many times it is called             called
       l  It is less efficient in
                                           l  In terms of execution
           terms of execution than             it is more efficient
           that of a macro because
           it includes overhead                because it does not
           instructions such as                have overhead
           Call and Return                     instructions
More about subroutines…
 l  Remember   subroutines can call other
     subroutines
 l  This is referred as structured code
Using Table Pointers
 l  Reading/writing
                values from/into the
   program memory one byte at a time
                                 TBLWT* / TBLWT*+ / TBLWT*-
                                           Table Latch (8-bit)
                                              Write into Memory
  TBLPTRU/H/L (21-bit)    Word
                                                  Read from the Memory
                         Program
                         Memory            Table Latch (8-bit)
                          (16-bit)   TBLRD* / TBLRD*+ / TBLRD*-
Table Example
                                   Rd the register content
                                   into Table Latch
Save in Prog Memory; Label the value as BUFFER
    TBLPTR(U/H/L)= 00 00 40
                       0x000040                               0x0002       TABLAT=0x02
       Pointing to the address
                                                             Program
                                                             Memory       W=0x02
                                                              (16-bit)
                                                                         REG10=0x02
Table Example                       LAB: Modify this program such that
                                   values 0xaa, 0xbb, 00cc stored in the
                                     program memory are copied into
                                        REG60,61,62, respectively
  TBLPTR = 00 00 40
                    0x000040    0x0002               TABLAT=0x02
    Pointing to the address
                               Program
                               Memory              W=0x02
                                (16-bit)
                                                  REG10=0x02
Examine this code:
                     See next slide…..
Answer the following:
l    At what location in the program memory CLEARME is built? Explain.
l    What are the contents of register 0x60, 0x61, etc. in the program memory?
l    Where is the location of FSR1 when the MARCO is called?
l    Where exactly does CLEARME macro does? How many registers are effected?
l    Where exactly does BYTECP macro does? How many registers are effected?
l    Modify the program using MACROs such that you perform the following tasks:
       l    Copy NINE values already stored in PROGRAM MEMORY locations, starting with locations
             0x80, into RAM locations starting with register 0x80. Assume the numbers are 1-9.
       l    Copy NINE values already stored in PROGRAM MEMORY locations, starting with locations
             0x80, into RAM locations starting with register 0x90. Assume the numbers are 1-9.
       l    Take the sum of all the values and locate the SUM in RAM location 0x100.
       l    Delete all the RAM registers starting with with register 0x90 - 0x09F
Example…..
 l  Modify  program 7.5.3 such that you can
     correctly take the average of any sum.
 l  The number of inputs can be up to 20
     non-zero unsigned values
   Unsigned Division Operation
       l    The PlCI8 MCU does not provide any divide
             instruction. Therefore, a divide operation must be
             synthesized by other instructions. A simple but popular
             divide algorithm in use today is the repeated
             subtraction method. This method performs unsigned
             divide operation. The hardware required for
             implementing the repeated subtraction method is
             shown in Figure below
       l    Before performing the repeated subtraction operation,
             one needs to load 0, the dividend, and the divisor info
             registers R, 0, and N, respectively. The carry flag is
             used to indicate whether the subtraction result is
             negative. The ALU can perform n-bit unsigned addition
             and subtraction operations. The repeated subtraction
             method consists of n steps. Each division step consists
             of three parts:
       l    Step 1
              l    Shift the register pair (R, 0) one place to the left.
       l    Step 2
              l    Subtract the contents of N from R and put the result back
                    in R if the result is positive.
       l    Step 3
              l    If the result of Step 2 is negative, then set the least
                    significant bit of 0 to o. Otherwise, set the least significant
                    bit of 0 to 1.
Reference: Huang
Division By Subtraction
References
 l  http://www.ece.msstate.edu/~reese/
  ece3724/lectures/chap6_subr_ptrs.pdf
Subroutine Documentation and
Parameter Passing
 l    Parameter passing
       l    Information exchanged between a calling program and a
             subroutine
 l    Subroutine documentation should include:
       l    Function of a subroutine: Brief description of what it does
       l    Input parameters: Information that should be provided by
             calling program to subroutine
       l    Output parameters: Information or results provided by
             subroutine to calling program
       l    Registers modified: List of registers changed by the
             subroutine
       l    List of subroutines called: List of other subroutines called by
             the called subroutine