Файл: Introduction to Microcontrollers. Architecture, Programming, and Interfacing of the Motorola 68HC12 (G.J. Lipovski, 1999).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 14.06.2025

Просмотров: 1412

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

PROBLEMS

!15

origin 800

; put at the beginning of SRAM

*

entry SOURCE

; provide entry address toHiwave

LCNTR:

ds.w

1

; 8-bit location counter

SIZE:

ds.b

; 8-bit number of symbols

SOURCE:

dc.b "ALF DC 7A"f $d,"LBl LD LB2",$d,"LB2 AD LBl,$d

LABELS

dc.b

32

; allocate 32-byte symbol table

*

Idx

SOURCE

; get source code string address

bsr

FINDLABEL ; look for label

bvs

FOUND

; if none found, skip. Note: y -> next symbol entry

movb

1, x+, y+1

; if found, copy first char from source to symbol table

movd

2, x+,2,y+ ; then copy 2nd and3rd characters to symbol table

movb

#LCNTR, 1, y + ; and copy location counter into symbol table

add

SIZE, 1

; increase label count

FOUND:

bra

*

; wait for debugger to stop program

*

FINDLBL: pshx

; save caller's pointer on the stack

leax

#LABELS

; x-> first symbol table row

Idab

1, X+

; get a character from source file

Idy

+1, X

; get next two characters from source file

Ida

SIZE

; A = number of symbols

*

branch F2

; go to end at F2 (in case there are zero items)

F1:

cpb

4, x+

; compare first character in B and move to nextrow

bne

F2

; if mismatch, try next by going to F2

cpy

3, x

; compare second, third character inY

clra

; clear A andcarry indicating success

Idx - 4 ,x

; make x->beginning of row found

bra

F4

; exit after balancing stack, putting pointer in Y

F2 :

dec

a

; count down accumulatorA

bpl

Fl

; go to Fl to do search if more to come

setc

; set carry to indicate failure

F3:

leay

SOURCE

; make y-> beginning of row found

pula

; restore caller's pointer from the stack

rts

; return to caller

Figure 4.27. FINDLBL Subroutine with Errors

27. Correct the assembly-language program in Figure 4.28. Do not change any lines that are already correct. This shortest subroutine LIST for "SA2" prints a line of the listing at the end of PASS2, after two bytes have been put into the object code. It prints the decimal line number ( < 10),the hexadecimal object code, and the source code. OUTHEX prints a binary number n in accumulator A as two digits (the hexadecimal representation of n). OUTCH places the ASCII character in accumulator A into a line of the listing, which is pointed to by the X register.



5

Advanced Assemblers,

Linkers, and Loaders

This chapter discusses the advanced assembler and the linker, which are tools needed to assemble large programs; it is written for the reader who intends to write a lot of assembly-language programs or large assembly-language programs. Whereas the last chapter gave sufficient detail for the reader to understand the assembler output of a C compiler and to embed a limited amount of assembly language code in a C procedure, this chapter provides additional tools and greater depth to enable you to write large assembly-language programs using a relocatable, conditional, or macro assembler, and to join together separately assembled programs using a linker program.

This chapter is optional. Current economics leads to writing programs in a highlevel language like C or C++ rather than in assembly language. Most programmers will not need to write a lot of programs in assembly language nor to write large programs in assembly language. Such readers can skip this chapter without losing any background needed for the rest of this book.

The first section introduces the complementary ideas of cross assembler and downloader. The next section describes the pair of ideas of relocatable assembler and linker program. Section 5.3 discusses how conditional assembly is used. The next section shows the power of macros in assembly-language programs. A final section recommends good documentation standards for programs written in assembly language.

Upon completion of this chapter, the reader should understand the tools needed for writing a large number of assembly-language programs or large assembly-language programs. He or she should have little difficulty writing assembly-language programs in the order of a couple of hundred lines long.

5.1 Cross Assemblers and Downloaders

In this section we introduce a close cousin of the assembler, the cross-assembler, which, like the assembler, converts sequences of (ASCII) characters into machine instructions. For the most part, this section's material is descriptive, almost philosophical, rather than precise and practical. It is important general knowledge, and it is included here because the reader should understand what he or she is doing when using a personal computer to assemble a program for a microcontroller.

119

5,4 Macro Assemblers

129

ADD:

MACRO

LDX

\1

LDAB

\2

CLRA

\@:

ADDA

1,X+

DBNE

B, \ @

ENDM

Figure 5.6. Loop Macro to Add Consecutive Values

letters to generate unique labels inside the macro itself. This capability is especially useful if a macro expansion has two or more "goto" labels in it; for without it, unambiguous labels could not be generated. Using the macro invocation number, each macro expansion generates labels that are different from the labels generated from the same macro that are expanded at a different time. For example, the macro in Figure 5.6, when implemented by ADD #M,N, adds the contents of the N bytes beginning in location M, putting the result in accumulator A.

A macro definition can use a macro defined earlier, or even itself (recursively). For macro assemblers that have conditional assembly, conditional directives within their definition can be used to control the expansion. The actual parameters of the macro can then be tested with these directives to determine how the macro is expanded. In particular, the IFC and IFNC directives can be used to compare a macro parameter, considered as a string, against any constant string. If a parameter is missing, it is a null string "\0." We can compare a given parameter, such as the second parameter, considered as a string denoted "\2," to a null string "\0." When the strings are equal, the second parameter is missing, so this condition can terminate the macro expansion.

The example in Figure 5.7 illustrates the use of recursion, conditional assembly, and early exiting of macros using MEXIT. You might want to use the ADDA instruction with a series of arguments, to add several bytes to accumulator A. If you wish, you can use a text editor to make copies of the ADDA instruction with different arguments. However, you can define a macro whose name is ADDQ, in which the body of the macro expands into one or more ADDA directives to implement the same effect. This ADDQ macro uses recursion to add one parameter at a time, up to eight parameters in this simple example, stopping when a parameter is missing (null string). When a null (missing) parameter is encountered, the macro "exits" by executing MEXIT, thereby not generating any more expansion or code.

ADDQ: MACRO

IFNC "\1",""

ADDA \1

ENDC

IFC "\2",""

MEXIT

ENDC

ADDQ \2,\3,\4,\5,\6,\7,\8

ENDM

Figure 5.7. Recursive Macro to Add up to Eight Values



PROBLEMS

133

PROBLEMS

1 . Give the SI and S9 records for the program in Figure 1.5.

2 . Give the program source code (in the style of Figure 1.5) for the following S- record: S10D0800FC0852FD0854137C08564E.

3 .

Write a shortest program segment to translate an ASCII SI record located in a 32-

character vector SRECORD, to write its data into SRAM.

4 .

Write a parameter file for the 'B32. Its SRAM, EEPROM, and flash memory are to

be the segments, with the same names; the sections are .data, .text, and .pgm; segment SRAM contains section .data; segment EEPROM contains section .text; and segment flash contains section .pgm. The starting address, named BEGIN, is to be put in $FFFE. The input file is to be progB32.o, and the output file is to be called progB32.abs.

5 . Write a parameter file for the 'A4. Its SRAM and EEPROM are to be the segments, with the same names; the sections are .data and .text; segment SRAM contains section .data; and segment EEPROM contains section .text. The starting address, named START, is to be put in $FFFE. The input file is to be progA4.o, and the output file is to be called progA4.abs.

6 . Write a parameter file for an expanded bus 'A4. Its internal SRAM, extended memory SRAM at $7000 to $7FFF, internal EEPROM at $4000 to $4FFF, and external ROM at $8000 to $FFFF, are to be the segments with the names ISRAM, ESRAM, EEPROM, and ROM; and the sections are .data , .edata, .text, and .pgm. Segment ISRAM contains section .data, segment ESRAM contains section .edata, segment EEPROM contains section .text, and segment ROM contains section .pgm. The starting address, named BEGIN, is to be put in $FFFE. The input files are to be camcorder1 .o, camcorder2.o, camcorderS.o, and carncorder4.o, and the output file is to be called camcorder.abs.

7 . Write a relocatable assembler program that uses fuzzy logic, that has a section .text that just calls fuzzy logic subroutines FUZZY and ADJUST one after another without arguments, and a section .pgm that has in it fuzzy logic subroutines FUZZY and ADJUST, which just have RTS instructions in them. Comment on the use of a relocatable assembler to break long programs into more manageable parts.

8. Write a relocatable assembler program that has a section .text that just calls subroutines OUTCH, OUTS, OUTDEC, and OUTHEX one after another. The argument in Accumulator A, for OUTCH, OUTDEC, and OUTHEX, is $41. The argument for OUTS, passed in index register X, is the address of string STRING1. A section .pgm has in it subroutines OUTCH, OUTS, OUTDEC, and OUTHEX, which just have RTS instructions in them, and the string STRING1, which is "Well done\r". Comment on the use of a relocatable assembler to break long programs into more manageable parts.

6

Assembly Language

Subroutines

Subroutines are fantastic tools that will exercise your creativity. Have you ever wished you had an instruction that executed a floating-point multiply? The 6812 does not have such powerful instructions, but you can write a subroutine to execute the floating-point multiplication operation. The instruction that calls the subroutine now behaves pretty much like the instruction that you wish you had. Subroutines can call other subroutines as you build larger instructions out of simpler ones. In a sense, your final program is just a single instruction built out of simpler instructions. This idea leads to a methodology of writing programs called top-down design. Thus, creative new instructions are usually implemented as subroutines where the code is written only once. In fact, macros are commonly used just to call subroutines. In this chapter, we concentrate on the use of subroutines to implement larger instructions and to introduce programming methodologies.

To preview

some of the ideas of this chapter, consider the following simple

subroutine, which adds the contents of the X register to accumulator D.

SUB: PSHX

; Push copy of X onto stack

ADDD

2, SP+

; Add copy into D; pop copy off stack

RTS

It can be called by the instruction

BSR SUB

Recall from Chapter 2 that the BSR instruction, besides branching to location SUB, pushes the return address onto the hardware stack, low byte first, while the instruction RTS at the end of the subroutine pulls the top two bytes of the stack into the program counter, high byte first. See Figure 6.1. In this figure, H:L denotes the return address and the contents of X is denoted XH:XL. Notice particularly that the instruction

ADDD 2,SP+

in the subroutine above not only adds the copy of the contents of X into D but also pops the copy off the stack so that the return address will be pulled into the program counter by the RTS instruction.

137