Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Introduction to Microcontrollers. Architecture, Programming, and Interfacing of the Motorola 68HC12 (G.J. Lipovski, 1999).pdf
Скачиваний:
191
Добавлен:
12.08.2013
Размер:
29.57 Mб
Скачать

162

Chapter 6 Assembly Language Subroutines

*SUBROUTINE DOTPRD

*PARAMETERS

*

PARV:

EQU

0

; Copy of vector V

PARW:

EQU

2

; Copy of vector W

PARDP:

EQU

4

; Dot product of V and W

*

 

 

 

*

LOCAL VARIABLES

 

*

 

 

 

TERM:

EQU

0

 

MBYTES: EQU

2

 

DOTPRD: LEAS

-NBYTES, SP ; Allocation for local variables

 

LDAA

PARV,X

 

 

LDAB

PARW,X

 

 

MUL

 

; First term of DP into D

 

STD

TERM, SP

; Store in local variable

 

LDAA

PARV+1,X

 

 

LDAB

PARW+1,X

 

 

MUL

 

; Second term into D

 

ADDD

TERM,SP

 

 

STD

PARDP, X

; Place dot product

 

LEAS

NBYTES, SP

; Deallocate local variables

 

RTS

 

 

a. Thesubroutine

LDX fTABLE

MOVW V, PARV, X ; Place copy of V into parameter

MOVW W, PARW, X ; Place copy of W into parameter

BSR DOTPRD ; Call Subroutine

MOVW PARDP, X, DTPD ; Copy result into global variable

b. Calling sequence

Figure 633. Calling Sequence for Passing Arguments in a Table

6.3 Passing Arguments by Value, Reference, and Name

Computer science students, as opposed to electrical engineering students, study the passing of parameters in high-level language subroutines on a different level than that used in the preceding section. We include this section to explain that level to you. On the one hand, this level is very important if, say, you are writing or using a subroutine that is used by a high-level language program and that subroutine has to conform to the properties discussed below. On the other hand, the differentiation between some of the characteristics discussed below is rather blurry in assembly language programs.

6,4 Calling And Returning Mechanisms

165

The extended local access of stacked local variables can be used with this technique. Consider the body of the subroutine after the PSHC instruction and before the PULC instruction as a program segment. The local variables are allocated just after the PSHC instruction that saves registers and are deallocated just before the PULC instruction that returns to the calling routine. You now look at the saved register values as stacked local variables of an outer program segment that includes the PSHD, PSHC, PULC, and PULD instruction. Using extended local access, you can read these registers and write into them, too. This allows you to output data in a register, even if the data are saved.

REGCC:

EQU

0

 

 

REGD:

EQU

1

 

 

REGX:

EQU

3

 

 

REGY:

EQU

5

 

 

*

 

 

 

 

SUB:

PSHY

 

; Save Y

 

 

PSHX

 

; Save X

 

 

PSHD

 

; Save D

 

 

PSHC

 

; Save CC

 

LDD

REGX, SP

; Get to caller's X value

 

ADDD

REGY, SP

; Add to caller's Y value

 

STD

REGY, SP

; Result to caller's Y value

 

PULC

 

; Restore CC

 

PULD

 

; Restore

D

 

PULX

 

; Restore

X

 

PULY

 

; Restore

Y

 

RTS

 

;Return

 

 

Figure 636. Saving and Restoring All the Registers

SUB

LBRA

SUBO

 

 

 

LBRA

SUB1

 

 

 

LBRA SUB2

 

 

SUBO:

; performinitialization

 

 

 

RTS

 

 

 

SUB1:

; perform output

 

 

 

RTS

 

 

 

SUB2:

; performtermination

 

 

 

RTS

 

 

 

Figure 637. A Subroutine with Multiple Entry Points

As an example of this, look at the preceding example again, now using saved registers as stacked local variables of an outer program segment. See Figure 6.36. This idea was expanded earlier to cover the passing of arguments on the stack. The basic idea is that you just have to know where the data are, relative to the current stack pointer SP, in order to access the data. Thus, access to the saved registers, the caller's stacked local

6.4 Calling And Returning Mechanisms

169

* original variables

 

RESULT; DS.W

1

*

*SUBROUTINE DOTPRD

*LOCALVARIABLES

*

TERM:

EQU

0

 

MBYTES: EQU

2

 

* Saved registers

 

 

*

 

 

 

REGCC:

EQU

0+NBYTES

; saved condition code register

REGB:

EQU

1+NBYTES

; saved accumulator B ~ note "backwards"

REGA:

EQU

2+NBYTES

; saved accumulator A —note "backwards"

REGX:

EQU

3+NBYTES

; saved index register X

REGY:

EQU

5+NBYTES

; saved index register Y

*

 

 

 

DOTPRD: LEAS

-NBYTES,SP

 

 

LDAA

REGA,SP

 

 

LDAB

REGB,SP

 

 

MUL

 

 

 

STD

TERM, SP

; First term to local variables

 

LDAA

REGX+lr SP

 

 

LDAB

REGY+1,SP

 

 

MUL

 

 

 

ADDD

TERM, SP

; Dot product into D

 

STAA

REGA, SP

; Dot product high byte to output parameter

 

STAB

REGB, SP

; Dot product low byte to output parameter

 

LEAS

NBYTES, SP

; Deallocate local variables

 

RTI

 

 

 

 

Figure 6.43. An SWI Handler

entry: MOVW

#DOTPRD,$FFP6

 

a. Initialization (done just once)

LDAA

#1

LDAB

#2

LDX

#3

LDY

#4

SWI

 

STD

RESULT ; Put in global location

BRA

*

b. Calling sequence (done each time the operation is to be performed).

Figure 6.44. Calling an SWI Handler