Page 174 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 174
6.2 Passing Parameters 151
The first method is that of passing parameters through registers, which is preferred
when the number of parameters is small. We will also use this method to illustrate the
idea of a calling sequence. See Figure 6.15. Suppose that the calling routine, the
program segment calling the subroutine, puts a copy of the vector V into registers A and
X and a copy of the vector W into registers B and Y, where, as.before, the low byte of a
16-bit register contains the 8-bit element. Both components of each vector are 1-byte
unsigned numbers. Assume that the dot product is returned in accumulator D, a
subroutine DOTPRD that performs the calculation is shown in Figure 6.15a. The
instructions in the calling routine shown in Figure 6.15b cause the subroutine to be
executed for vector V equal to (2,6) and vector W equal to (7,3). Notice that the values
in A and B have been changed by the subroutine, because an output parameter is being
returned in D. The sequence of instructions in the calling routine that handles the
placement of the input and output parameters is termed the calling sequence. In our
calling sequence we have, for convenience, assumed that constant input parameters are
given to DOTPRD while the output parameter in D is copied into the global variable
DTPD. These constants and the global variable could just as easily have been stacked
local variables for the calling routine.
To emphasize that a calling sequence is in no way unique, suppose that the calling
routine has vectors that are pairs of 8-bit local variables on the stack, labeled LV and LW,
as offsets to the stack pointer. To compute the dot product of LV and LW, execute the
calling sequence in Figure 6.15c.
We have, for simplicity, omitted the binding, allocation, and deallocation of the
local variables of the calling routine. The point of this second example is to stress that
any calling sequence for the subroutine DOTPRD must load copies of the vectors for
which it wants the dot product into X and Y and then call DOTPRD. It must then get the
dot product from D to do whatever it needs to do with it. From a different point of view,
if you were to write your own version of DOTPRD, but one that passed parameters in
exactly the same way, your version could not directly access the global variable LV used
in the calling sequence in Figure 6.15. If it did, it would not work for the catling
sequence in Figure 6.14c.
Parameters are passed through registers for most small subroutines. The main
limitation with this method of passing parameters is that there are only two 16-bit
registers (you do not pass parameters in the stack pointer SP register itself), two 8-bit
registers, and a few condition code bits. Although this limits the ability of the 6812 to
pass parameters through registers, you will, nevertheless, find that many, if not most, of
your smaller subroutines will use this simple technique.
The next technique we discuss is that of passing parameters through global
variables. We include it because it is used in small microcomputers like the 6805, but
we discourage you from using it in larger machines like the 6812. It is easy to make
mistakes with this technique, so much so that most experienced programmers avoid this
method of passing parameters when other techniques are available. Figure 6.16 shows a
coat hanger diagram that illustrates how incorrect results can occur when parameters are
passed with global variables. Notice in particular how subroutine B writes over the vaiue
of the global variable passed by the calling routine to subroutine A, so when subroutine
A performs the load instruction, it may not have the calling routine's value.