Файл: Introduction to Microcontrollers. Architecture, Programming, and Interfacing of the Motorola 68HC12 (G.J. Lipovski, 1999).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.06.2025
Просмотров: 1408
Скачиваний: 0
100 |
Chapter 4 Assembly Language Programming |
ORG $800
K:DC . b "ALPHA", 0 ; a NULL-terminated character string for part (b).
OUTPUT: |
Ds. b |
10 |
; storage buffer for output characters for part (c). |
|
OUTPTR: |
DC . w |
OUTPUT |
; pointer to the above buffer |
|
a. Data |
||||
PRINT: |
LDX #K |
; get address of string |
||
NEXT: LDAA 1, X+ |
; get a character of string, move pointer |
|||
BEQ |
END |
; if it is NULL, exit |
||
BSR |
PUT |
; otherwise print the character in A |
||
BRA |
NEXT |
; repeat the loop |
||
END: |
SWI |
; return to the debugger |
||
b. Calling PUT |
||||
PUT: |
PSHX |
; save |
||
LDX |
OUTPTR |
; get pointer to output string |
||
STAA 1, X+ |
; save character, move pointer |
|||
STX |
OUTPTR |
; save pointer |
||
RTS |
; return |
|||
PULX |
; restore |
|||
Figure 4.8. Print Program
programming effort. From now on, we will not write machine code, but we will write (ASCII) source code and use the assembler to generate the machine code.
The first three examples illustrate character string processing. The first example prints out a character string. The second transfers a character string from one location to another. The third compares two strings, returning 1 if they match. These examples are similar to PUT, STRCPY, and STRCMP subroutines used in C.
Figure 4.8b's program prints a string of characters using a subroutine PUT, like problem 3.15. Such strings often end in a NULL (0) character. The program reads characters from the string using LDAA 1, X+, and calls PUT to print the character in A. This also sets the condition code Z bit if the byte that was loaded was NULL, which terminates execution of the loop. An analogous program inputs data from a keyboard using the subroutine GET and fills a vector with the received characters until a carriage return is received. These programs can be generalized. Any subroutine that uses characters from a null-terminated character string can be used in place of PUT, and any subroutine that puts characters into a string can be used instead of GET.
PUT and GET are actually I/O procedures we show in §11.8, which require considerable understanding of I/O hardware. We don't want to pursue the actual PUT and GET subroutines quite yet. Instead, we replace the actual PUT and GET subroutines with a stub subroutine (Figure 4.8c). After stopping the computer, examine the string OUTPUT to see what would be output. Similarly, a stub subroutine can be used instead of GET, to "input" characters. The sequence of input characters is preloaded into a string.
Our second example (Figure 4.9) copies a null-terminated character string from one location to another. The original string is generated by the assembler and downloaded into memory, using Src DC . b. The program copies it to another part of memory at Dst Ds . b. Note that the NULL is also copied to the destination string.
104 |
Chapter 4 Assembly Language Programming |
ORG |
$800 |
JSR |
PASSI |
JSR |
PASS2 |
SWI |
|
Figure 4.15. Assembler Main Program |
The first instruction, which will be stored in location 0, loads the contents of location 3. The left two bits, the opcode, are 00, and the address of location 3 is 000011, so the machine code is 03 in hexadecimal. The next instruction's opcode is 01 for add; its effective address is 000100. The last instruction's opcode is 10 for store; its effective address is 000101. The source code shown in Figure 4.13b includes directives to initialize location 3 to $12, location 4 to $34, and location 5 to 0.
The assembler is written as two subroutines called PASSI and PASS 2. This program segment illustrates the usefulness of subroutines for breaking up a large program into smaller subroutines that are easier to understand and easier to debug.
The data are defined by assembler directives, generally written at the beginning of the program. See Figure 4.16. They can be written just after the program segment shown in Figure 4.15. The first directive allocates a byte to hold the object pointer (which is the location counter). The second directive allocates and initializes the ASCII source code to be assembled. The next two lines allocate two eight-element vectors, which will store the machine code and symbol table.
LCNTR: |
Ds. b |
1 |
; index used to store object code, which is the location counter |
SOURCE: |
Dc.b " |
LA",$d," AB",$d," S C",$d,"A D 12",$d,"B D 34",$d,"C D00",$d,0; |
|
OBJECT: |
Ds.b |
8 |
; machine code |
LABELS: |
Ds. b |
8 |
; symbol table |
Figure 4.16. Assembler Directives |
|||
PASS 1: |
CLR |
LCNTR ; clear index to object code vector |
|
LDX |
#SOURCE ; begin source scan: x-> first letter in source string |
||
LDY |
#LABELS ; y-> first symbol |
||
P11: |
LDAB |
1, x+ ; get the line's first character to B and move x to next character |
|
BEQ |
PI4 |
; exit when a null character is encountered |
|
CMPB |
#' |
' ; if B is a space |
|
BEQ |
PI3 |
; get opcode by going to PI3 |
|
STAB |
1, y+ ; move character to symbol table |
||
MOVE |
LCNTR, 1,y+ ; put label value into symbol table |
||
P13: |
LDAB |
1, x+ ; load B with character, move pointer |
|
CMPB |
#$d |
; compare to carriage return which ends a line |
|
BNE |
P13 |
; until one is found. Note that x-> next character after this. |
|
INC |
LCNTR ; increment location counter (we are processing the next line) |
||
BRA |
PI 1 |
; go to PI 1 to process the next line |
|
P14: |
RTS |
||
Figure 4.17. Assembler Pass 1
4.6 Summary |
107 |
*Get hexadecimal value
*entry: X->first character of hex number
* |
exit: |
A:value, X->nextcharacter after hex number |
|
* |
saved: |
B,Y |
|
* |
|||
GETHEX: |
BSR |
GH1 |
; convert ascii character to a nibble |
LSLA |
; move to high nibble |
||
LSLA |
|||
LSLA |
|||
LSLA |
|||
PSHA |
; save on stack |
||
BSR |
GH1 |
; convert ascii character to a nibble |
|
ORAA |
1, sp+ ; pop and combine |
||
* |
RTS |
||
GH1: |
LDAA |
1, x+ ; get next symbol |
|
CMPA |
#'9 ' |
||
BLS |
GH2 |
||
SUBA |
#7 |
||
GH2 : |
SUBA |
#' 0 ' |
; subtract ascii 0 |
RTS |
|||
Figure 421.Convert ASCII Hex String to a Binary Number
The reader should observe that this subroutine, PASS2, is broken into subroutines GETOPCD, GETHEX, and FINLBL. Each of these subroutines is more easily understood and debugged than a long program PASS2 that doesn't use subroutines. Each subroutine corresponds to an easily understood operation, which is described in the subroutine's header. This renders the subroutine PASS2 much easier to comprehend.
The contents of the vector OBJECT will be downloaded into the target machine and executed there. The assembler permits the programmer the ability to think and code at a higher level, not worrying about the low-level encoding of the machine code.
The reader should observe the following points from the above example. First, the two-pass assembler will determine where the labels are in the first pass. Thus, labels that are lower in the source code than the instructions that use these labels will be known in the second pass when the instruction machine code is generated. Second, these subroutines further provide many examples of techniques used to convert ASCII to hexadecimal, used to search for matching characters, and used to insert data into a vector.
4.6 Summary
In this chapter, we learned that an assembler can help you write much larger programs than you would be able to write by hand coding in machine code. Not only are the mnemonics for the instructions converted into instruction opcode bytes, but also symbolic addresses are converted into memory addresses. However, every new powerful
PROBLEMS |
111 |
13. Write a shortest assembly-language (source code) subroutine that concatenates one null-terminated string onto the end of another null-terminated string, storing a null at the end of the expanded string. Assume that on entry, X points to the first string, Y points to the second string, and there is enough space after the second string to fit the first string into this space. This program is essentially the C procedure strcat().
14. Write a shortest assembly-language (source code) subroutine to compare at most n characters of one null-terminated string to those of another null-terminated string, similar to Figure 4.10. Assume X points to the first string, and Y points to the second string, and A contains the number n. Return carry set if and only if the strings match.
15.Write a shortest assembly-language (source code) subroutine that builds a symbol table as in Figure 4.12a but stores six-letter symbolic names and a two-byte value in each symbol table row. Upon entry to the subroutine, X points to the first of the six letters (the other letters follow in consecutive locations), and accumulator D contains the two-byte value associated with this symbol. The symbol table is stored starting at label LABELS, and the number of symbols (rows) is stored in one-byte variable SIZE.
16.Write a shortest assembly-language (source code) subroutine that searches a symbol
table as in Figure 4.12b but searches six-letter symbolic names having a two-byte value in each symbol table row. Upon entry to the subroutine, X points to the first of the six letters (the other letters follow in consecutive locations). The symbol table is stored starting at label LABELS, and the number of symbols (rows) is stored in one-byte variable SIZE. The subroutine returns with carry bit set if and only if a matching symbol is found; then Y points to the beginning of the row where the symbol is found.
17 . Write a shortest assembly-language (source code) program that finds themaximum MAX of N 4-byte signed numbers contained in array Z where N < 100. Your program should have in it the assembler directives
N |
DS |
1 |
MAX |
DS |
4 |
Z |
DS.L |
100 |
and be position independent. How would your program change if the numbers were unsigned?
18. Write an assembly-language program that finds the sum SUM of two 4-byte signed magnitude numbers NUM1 and NUM2. The result should also be in signed-magnitude form. Your program should include the assembler directives
ORG |
$800 |
|
N |
DS |
1 |
NUM1 |
DS |
4 |
NUM2 |
DS |
4 |
SUM |
DS |
4 |