Character String Operations (Microcontrollers)

4.4
Before we look into an assembler, we will study some operations that copy, search, and manipulate character strings. These operations make it easier to understand how an assembler works, which we cover in the next section. They also provide an opportunity to show how assembly-language source code is written, in order to simplify your
Print Program
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.
Character Move Program Segment and Data
Figure 4.9. Character Move Program Segment and Data
Our third example (Figure 4.10) compares one null-terminated character string with another. Both strings are downloaded into memory starting at label Src and Cmprd. We examine several cases of execution right after this program listing.
We examine several cases with this comparison program. Consider the case where Src is “BETA. ” The first time after label NEXT, the CMPA instruction clears the Z condition code bit, and the program goes to BAD to clear A and exit. Consider the case where Src is “ALPH.” The fifth time at label NEXT, the LDAA instruction sets the Z condition code bit, and the program goes to EXIT where it tests the byte pointed to by Y, which is the ASCII letter A, so it goes to BAD to again clear A and exit. Consider the case where Src is “ALPHAS .” The sixth time after label NEXT, the CMPA instruction clears the Z condition code bit, and the program goes to BAD to clear A and exit. Finally, consider the case where Src is “ALPHA.” The fifth time at label NEXT, the LDAA instruction sets the Z condition code bit, and the program goes to EXIT where it tests the byte pointed to by Y, and because it is zero, the program sets A to 1 and exits. If the two strings are identical, the program ends with 1 in A, otherwise it ends with 0 in A.
The next example illustrates a comparison of a letter provided in accumulator A, to find a match among a collection of four letters L, A, S, and D, assuming it may not be any other letter. The number left in B is 0 if the letter is L, 1 if it is A, 2 if S and 3 if D. Two ways to do this are (1) execute compares with immediate operands, and (2) store the letters in a string and compare the unknown letter to each letter in the string. See Figure 4.11. Except for small collections of letters, the string method is best.
Character String Compare Program Segment and Data
Figure 4.10. Character String Compare Program Segment and Data
Dictionary Program Segments
Figure 4.12. Dictionary Program Segments
Machine and Source Code
Figure 4.13. Machine and Source Code
Finally, we show a pair of programs that will build and search a dictionary (of letters). Figure 4.12a’s program segment is executed each time a letter in accumulator A is inserted into the dictionary. The letter has a numerical “value” associated with the letter in B. The program segment in Figure 4.12b searches the dictionary. On entry, a letter is put in A. The “value” of the letter is left in B when the segment is completed.
These simple search programs can be fairly easily expanded for searching for longer strings of characters, or counting characters, rather than testing for a NULL, to determine when to terminate the search. Variations can handle the case where the comparand is not found. However, these are all linear searches in which the time to search for an item in the dictionary is linearly related to the number of elements in the dictionary. For large dictionaries, linear searches are entirely too slow; linked lists (§10.4) are much faster. However, linear searches are adequate for the simple assembler in §4.5.


Next post:

Previous post: