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

6,1 Local Variables                                                 145


        TERM:      EQU       0
        VI i       EQU       2
        ¥2:        EQU       3
        Ml:        EQU       4
        W2:        EQU       5
        MBYTES: EQU          6
                   LEAS      -MBYTES, SP      ; Allocate all local variables
                   MOVB      #1, VI, SP       ; Initialize V(l)
                   MOVB      #2, V2, SP       ; Initialize V(2)
                   MOVB      #3, Wl, SP       ; Initialize W(l)
                   MOVB      #4, W2, SP       ; Initialize W(2)
                   LDAA      VI,SP            ; VI into A
                   LDAB      Wl, SP           ; Wl into B
                   MUL                        ; First term is now in D
                   STD       TERM, SP         ; Store first term in TERM
                   LDAA      V2, SP           ; V2 into A
                   LDAB      W2, SP           ; W2 into B
                   MUL                        ; Calculate second term
                   ADDD      TERM, S P         ; Add in TERM; dot product in D
                   LEAS      NBYTES, SP       ; Deallocate locals; balance stack
                  Figure 6.10. Using Symbolic Names for Stacked Local Variables
            A problem with the stack approach is that remembering that a variable is at 2, SP
        (or is it at 5, SP?) is error prone, compared to giving names to variables (see Figure
        6.7). We need to give names to the relative locations on the stack; that is, we need to
        bind the variables. We discuss two ways to bind names to locations on the stack: the
        EQU and DS assembler directives. See Figure 6.10.
            Since TERM is on top of the stack, the EQU assembler directive can bind the value
        of the name TERM to the location 0, SP; then TERM, SP can access it. Note that you
        bind the name of the container TERM to 0, SP and not the contents of TERM to 0 with
        the EQU directive. That is, we use 0 wherever we see TERM, and we use it in calculating
        the address with TERM as an offset in index addressing with the SP register. Similarly,
        we can bind VI to 2 , SP and W2 to 5, SP. Also, the offsets used in the LEAS
        instructions to allocate and deallocate the local variables can be set when they are defined.
        Initialization is changed a bit to make NBYTES easier to use, but the effect is the same.
        The program segment to calculate the dot product can now be rewritten as in Figure
        6.10. (We write the changed parts in boldface, here and in later examples, to focus your
        attention on them.) Note that each statement is quite readable without comments.
        However, good comments are generally still valuable.
            As described above, this technique requires the programmer to calculate the values
        for the various labels and calculate the value for NBYTES. Adding or deleting a
        variable requires new calculations of these values. Figure 6.11 shows how this can be
        avoided. With this use of the EQU directive, each new stacked local variable is defined in
        terms of the local variable just previously defined plus the number of bytes for that local
        variable. Insertions or deletions of a stacked local variable in a segment now requires
        changing only two lines, a convenience if the number of local variables gets large.
   163   164   165   166   167   168   169   170   171   172   173