Page 163 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 163
140 Chapter 6 Assembly Language Subroutines
For the purpose of this discussion, we assume that the program segment has
information passed into it by its input parameters (or input arguments) and that the
results of its computation are passed out through its output parameters (or output
arguments). Any variables used in the segment for its computation but not used
elsewhere, and which are not parameters are called local variables. The program segment
can be thought of as a box with the parameters and variables that relate to it. Some of
the parameters may be global variables—variables that are, or can be, used by all
program segments. If you have learned about sequential machines, the input parameters
are like the inputs to the sequential machine, the local variables are like the internal
states of the machine, and the output parameters are like the outputs of the machine. As
a sequential machine can describe a hardware module without the details about how the
module is built, one can think about the input and output parameters and local variables
of a program segment without knowing how it is written in assembly language. Indeed,
one can think of them before the segment is written.
Consider the following example. Suppose that we have two vectors V and W, each
having two I-byte elements (or components) V (1), V ( 2 ) and W (1), W {2 ). We want
to compute the inner product
V(1)*W(1) + V(2)*W(2) (1)
which is often used in physics. Input parameters are the components of V and W, and the
one output is the dot product result. The components of V and W are assumed to be 1-
byte unsigned numbers; for instance, assume that VI is 1, V2 is 2, Wl is 3, and W2 is
4. The 2-byte dot product is placed in accumulator D at the end of the segment, but it
becomes clear that we will have to store one of the products in expression (1) somewhere
while we are computing the second product in accumulator D. This 2-byte term that we
save is a local variable for the program segment we are considering. It may also be
convenient to place copies of the vectors V and W somewhere for easy access during the
calculation. These copies could also be considered local variables. We will continue this
example below to show how local variables are stored in a program segment.
We first consider the lazy practice of saving local variables as if they were global
variables, stored in memory and accessed with page-zero or direct addressing. One
technique might use the same global location over and over again. Another technique
might be to use differently named global variables for each local variable. While both
techniques are undesirable, we will illustrate them in the examples below.
A single global variable, or a small number of global variables, might be used to
hold all local variables. For example, assuming that the directive TEMP DS 2 is in the
program, one could use the two locations TEMP and TEMP+1 to store one of the 2-byte
local variables for the dot product segment. Figure 6.4 illustrates this practice. Six bytes
are needed for various temporary storage. We first allocate six bytes using the declaration
TEMP DS 6 . Then the values of these variables are initialized by MOVE instructions.
Next, these local variables are used in the program segment that calculates the inner
product. The algorithm to compute the inner product is clearly illustrated by comments.
Using this approach can lead to the propagation of errors between segments
discussed earlier. This can be seen by looking at the "coat hanger" diagram of Figure 6,3,
A horizontal line represents a program segment, and a break in it represents a call to a
subroutine. The diagonal lines represent the subroutine call and its return. Figure 6,3