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