Page 167 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 167

144                                Chapter 6 Assembly Language Subroutines
















              Figure 6.8. Nested Subroutines Using Local Variables Stored on the Stack

            Let's now look at our dot product example in Figure 6.7, where we will initialize
        the copies of V(l), V(2), W(l), and W(2) to have values 1, 2, 3 and 4, respectively. The
        first term of the dot product shown in formula (1), which will also be placed on the
        stack, will be denoted TERM. Notice how the simple rule for balancing the stack is used
        in this segment. If the stack pointer were changed in the interior of the segment, offsets
        for local variables would change, making it difficult to keep track of them. As it is now,
        we have to determine the offsets from the stack pointer for each local variable. The local
        variable TERM occupies the top two bytes, the local variables V(l) and V(2) occupy the
        next two bytes, and the local variables W(l) and W(2) occupy the next two bytes.
            Figure 6.8 illustrates how the use of the stack avoids the aforementioned problem
        with global variables. Because the stack pointer is moved to allocate room for local
        variables, the temporary variables for the outermost program are stored in memory
        locations different from those that store local variables of an inner subroutine like B.
            The advantage of using the stack can be seen when two subroutines are called one
        after another, as illustrated in Figure 6.9. The first subroutine moves the stack pointer to
        allocate room for the local variable, and the local variable is stored with an offset of 0 in
        that room. Upon completion of this subroutine, the stack pointer is restored, deallocating
        stacked local variables. The second subroutine moves the stack pointer to allocate room
        for its local variable, and the local variable is stored with an offset of 0 in that room.
        Upon completion of this subroutine, the stack pointer is restored, deallocating stacked
        local variables. Note that the same physical memory words are used for local variables in
        the first subroutine that was called, as are used for local variables in the second
        subroutine that was called. However, if the second subroutine were called from within the
        first subroutine, as in Figure 6.8, the stack pointer would have been moved, so that the
        second subroutine would not erase the data used by the first subroutine. Using the stack
        for local variables conserves SRAM utilization and prevents accidental erasure of local
        variables.









             Figure 6.9. Local Variables Stored on the Stack, for Successive Subroutines
   162   163   164   165   166   167   168   169   170   171   172