Introductory Example and Assembler Printout (Microcontrollers)

4.1
We now consider a simple example to introduce you to assembly-language programs. Consider a program that obtains the maximum of a sequence of numbers. We will assume that this sequence consists of 16-bit unsigned numbers stored consecutively in memory, high byte first for each number. This data structure is called a vector or (one-dimensional) array. The name of the vector will be the location of the first byte of the vector, so that the high byte of the ith number in the vector (i = 0, 1, 2, . . .) can be found by adding 2*i to the vector name. Suppose then that Z is a vector of four 16-bit two’s-complement numbers beginning in location $86a with N stored in location $868. The ith number will be denoted Z(i) for i = 0 through N – 1. We want a program that finds the maximum of these numbers, putting it in locations $868 and $869.
One possible program for this, following the style of previous examples, is shown in Figure 4.1. We have arbitrarily started the program at address $89C.
Looking at the preceding program, we certainly would like to use just the mnemonics column with the variable addresses and the labels for the branches and let the assembler generate the other two columns, that is, do what we have been doing by hand. We would also like to be able to use labels, also called symbolic addresses (or just symbols) for the memory locations that hold the values of variables. The meaning of symbolic addresses is explored in greater detail in the next topic. We use them in this section to get the main idea (they are used before dissecting them carefully). The use of symbolic addresses allows program segment (2) to be replaced by program segment (3).
tmpD-16_thumb
(2)
tmpD-17_thumb
<3)
Program MAX
Figure 4.1. Program MAX
 Assembler Source Code for the Program MAX
Figure 4.2. Assembler Source Code for the Program MAX
Program segment (3) is clearer than program segment (2). An assembly-language source code for the program in Figure 4.1 is shown in Figure 4.2.
Putting this assembly-language program into the assembler yields the output listing shown in Figure 4.3. Although some new mnemonics have crept in, we can nevertheless see that we do not have to refer to actual addresses, only labels. We can see that we have not had to calculate relative offsets for the branching instructions, and we have not had to find memory locations or machine code. We now look into some of the details.
An assembly-language source statement takes the following form, where the fields, which are groups of consecutive characters, are separated by one or more one spaces:
Label Field Operation Field Operand Field Comment
The label field and the comment field may be empty and, depending on the operation, the operand field may be empty.


Label Field

A label (or symbolic address), if present, must have a letter as the first character and continue with letters, numbers, periods, or underscores. If a line’s first character is an asterisk (*) or semicolon (;), the whole line is treated as a comment. Finally, labels that are identical to register names are not allowed (e.g., A, B, CC, X, Y, S, SP, PC, D, and PCR). The label ends in a colon (:). In some assemblers the colon is mandatory after a label; in some it cannot be used; and in others it is optional.

Operation Field

Except for comment lines, the operation field must consist of an instruction mnemonic or assembler directive (more about these later). The mnemonic must be written with no spaces: CLRA, TSTB, ADDD, and so on.
Operand Field
The operand field contains the addressing information for the instruction. Although numbers can be used to specify addresses, you will find that symbolic addresses are generally much easier to use in the operand field. For example, using the symbolic
Table 4.2. Addressing Modes
Addressing ModestmpD-21_thumb

Comment Field

In the comment field, the programmer can insert short comments stating the purpose of each instruction. The comment must begin with a semicolon (;). In other assemblers, the comments begin one or more blanks after the operand field and are printed in the assembler listing but are otherwise ignored by the assembler.
In summary, writing an assembly-language program is a lot easier than writing machine code by hand. You can use symbolic addresses, letting the assembler determine where to put them and letting the assembler make sure that the instructions have the right operand values. You do have to conform to the rules of the language, however, and you have to spell the mnemonics exactly the way the assembler wants to recognize them. Although it would be nice to be able to just talk to the computer and tell it what you want it to do using conversational English, an assembler can barely understand the mnemonics for the instructions if you write them correctly and carefully. Nevertheless, writing assembly-language programs is easier than writing hexadecimal machine code.
Assembler Listing for the Program MAX
Figure 43. Assembler Listing for the Program MAX
The listing, shown in Figure 4.3, generally mirrors the source code but includes machine code and storage information. The listing line begins with a pair of line numbers. The first number is an absolute line number used for error messages, and the second is a relative line number used for include files and macro expansions discussed in the next topic. The hexadecimal location of the instruction is given next; then the hexadecimal machine code is displayed. Finally, the source code line is shown.

Next post:

Previous post: