Файл: 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