Page 166 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 166
6.1 Local Variables 143
enter: MOVE #4,1,-SP ; Allocate and initialize W(2)
MOVE # 3,1, - S P ; Allocate and initialize W( 1)
MOVE #2,1,-SP ; Allocate and initialize V(2)
MOVE # 1,1, - S P ; Allocate and initialize V( 1)
LEAS - 2 , SP ; Allocate room for term
LDAA 2,SP ;V(l)intoA
LDAB 4,SP ;W(l)intoB
MUL ; The value of first term is now in D
STD 0 , SP ; Store first term in TERM
LDAA 3,SP ;V(2)intoA
LDAB 5,SP ;W(2)intoB
MUL ; Calculate second term
ADDD 0, S P ; Add in TERM; dot product is now in D
LEAS 6,SP ; Deallocate local variables; balance stack
Figure 6.7, Inner Product Program Segment Utilizing Local Variables on the Stack
We now look more closely at this rule to show how local variables can be bound,
allocated, deallocated, and accessed using the stack. Binding means assigning an address
(the actual address used to store the variable) to a symbolic name for a variable.
Allocation of a variable means making room for that variable in memory, and
deallocation means removing the room for that variable. Accessing is the process of
finding that variable which, for stacked local variables, will be on the stack. An input
parameter supplies a value to be used by the program segment. While input parameters
are usually not changed by the program segment, local variables and output parameters
that are not also input parameters generally need to be initialized in the program
segment. That is, before any instruction reads a value from them, a known value must be
written in them. A stacked local variable or output parameter is usually initialized
immediately after the entry point of the program segment.
Stacked local variables are bound in two steps. Before the program is ran, the
symbolic address is converted to a number that is an offset that is used in index
addressing with the stack pointer. The binding is completed when the program is
running. There, the value in the stack pointer SP, at the time the instruction is executed,
is added to the offset to calculate the actual location of the variable, completing the
binding of the symbolic address to the actual address used for the variable. This two-step
binding is the key to reentrant and recursive subroutines, as discussed in Chapter 3.
We will allocate stacked local variables in a balanced program segment using LEAS
with negative offset and instructions like PSHX, which make room for the stacked local
variables. We will deallocate the variables using LEAS with positive offset and
instructions like PULX, which remove the room for the local variables. We will bind and
access stacked local variables in a couple of ways to illustrate some alternative techniques
that you may find useful. First, to access local variables, we use explicit offsets from the
stack pointer, reminiscent of the programming that you did in the first three chapters.
Then we use EQU, ORG, and DS directives to bind local variable names to offsets for the
stack pointer. This allows symbolic names to be used to access these local variables,
taking advantage of the assembler to make our program clearer.