Example Program Using MiniIDE and AS12 (Tewksbury) The following reviews the use of the MiniIDE assembly language programming tools for the HC12. I recommend that you download the most recent version from MGTEK. The following program is given on page 59 of your textbook. This is a standard example of an assembly language program. The first column contains labels. The equ statement says that the label "N" appearing anywhere in the program should be replaced (rewritten) as the decimal number "20". The line org $800 places the memory location counter of the assembler at memory location $800. The memory location will be used for the next instruction and then continually incremented as additional instructions follow. Here, memory space (but not a value) is allocated at memory location $800 for a "variable name" max_val. In the assembly language programs, whereever max-val appears, it will be replaced by the memory location $800. The next line (org $1000) resets the memory location counter to $1000. This restarts the memory location counter. The label loop is associated with the start of the location of the instruction ldaa max_val. Whenever the program encounters loop, it will be replaced by the memory location associated with loop. Similarly, chk_end is a label that is associated with the memory location of the start of the instruction dex. Following the chk_end line of the program, you will see a branch statement to loop. The assembler will replace loop with the memory location associated with loop, causing the program to return to the line ldaa max_val. The odd line starting with forever is used to halt the program. When executed, it causes the same instruction to be continually repeated. There will be some memory location counter value associated with the next instruction following the forever instruction. That establishes the memory address associated the db assembler directive, which stores the 8-bit numbers 1, 3, 5, ... at successive locations starting with the memory location associated with that line. N: equ 20 org $800 max_val: rmb 1 org $1000 ldaa array staa max_val ldx #array+n-1 ldab #N-1 loop: ldaa max_val cmpa 0,x bge chk_end ldaa 0,x staa max_val chk_end: dex dbne b,loop forever: bra forever array: db 1,3,5,6,19,41 end The steps involved in creating a new program using MiniIDE are as follows. Step 1: Create Program Text File: Select "NEW" under the File pull-down menu and entering the program above. This is merely a text-file when first created. The upper part of Figure 1 shows the program entered. The lower box of the window will be empty when your first create the text file. Step 2: Create Assembler Program File: Save the text file above by selecting a name (I'll use example) and adding the .asm extension when first saving the program file. It is important to add the .asm extension - otherwise MiniIDE will treat the file saved as a simple text file (and it will not even appear in the list of files when using the "OPEN" pulldown to reopen and edit the program. You now have the "assembler program file." Figure 1: The assembly language program Step 3: Build the Assembler Program" Running "Build" causes the multi-pass assembler (AS12) to "compile" the program file. This relates to evaluating the various labels used and identifying the values associated with each label. It also involves mapping the assembler directive operations into the generation of the executable binary program. Upon completion of the "build" operation, you will find information related to program errors detected and two new files appearing in the directory where the program was saved. The screen shot shown in Figure 1 was actually the screen shot appearing after running "build" and is the reason why the lower box contains information. The upper box containing the program text is the same as you would have seen in Step 1. The lower box in Figure 1 says there are two warnings but no errors (meaning you could use the program as written. there are two warnings and no errors. This means that you can run the resulting program. The first warning line says that the error occurred on line 3 of the file example.asm. The starting location of the error on line 3 is given as column 13. Looking at the upper part of Figure 1, the third line is the statement beginning max_val. The line giving the first warning continues beyond the screen shown to say that the warning relates to an obsolete directive. The only directive in the line is the rmb directive. With some checking you will find that other assembler directives are preferred for reserving memory for a label. The build operation generates the AS12 file with warnings and error listings shown in Figure 1 plus two additional files. One (for our example name example) is a long listing file with a .lst extension (e.g., example.lst) giving details on what the assembler did. The second is the S12 record file with the .s12 extension (e.g., example.s12) that is the binary file sent to the microcontroller to install the program. The .s12 file may not be visible in your directory but you should be able to find it using a text editor and selecting "open." Step 4: Looking at the "Long" File Listing: Figure 2 shows a screen shot of the example.lst file for the program given earlier. The first column gives the line number of the assembler instruction. The warnings and errors are included immediately before the instruction containing the error. The second column gives the starting memory location of the instruction. Instructions can contain multiple operand bytes and we distinguish between the starting memory location of an instruction and continuations of memory locations to complete the instruction. If there is no starting address, the line is not an instruction - it is an assembler directive to set memory locations or values of labels. The third column gives the instruction opcode followed by the instruction operands (if any) in binary coded form. These are the actual bytes (they are given in hexadecimal format) defining the instruction. Columns 4, 5, and 6 given the assembly language (English) instructions (opcode such as ldaa followed by the operands. These columns are what appeared in your original program generated using a text editor. From this listing, you can obtain the details of any instruction. For example, line 9 represents the instruction loop: ldaa max_val Here, loop is a label identifying the memory location associated with this instruction. This lable is used later to implement a branch back to the same instrction. ldaa is the nmemonic for the opcode (load accumulator a). max_val is a label defined on line 3 as being the current memory address (i.e., address $800). The memory location of and the binary code for this instruction (columns 2 and 3) are (in hexadecimal format) Memory location of instruction = 100B (the starting memory location, column 2, of the instruction) Instruction opcode = B6 Operand is memory location 0800 (the memory location where max_value is stored) Step 5: Looking at the S-Record sent to the microcontroller: As discussed above, column 3 of the long listing in Figure 2 contains the binary coded values of the opcode and operands associated with an instruction. This is the raw program data that is loaded into the 68HC12 microcontroller to execute the original program written in English in Step 1. The program data is transferred to the microcontroller through the serial port connection between the PC and the HC12EVB as a stream of data bits. There is a specific format for that stream of bits, called the S-Record. Figure 3 shows the data of the S-record file (the file with the .s12 extension). As noted earlier, you can find this file in your MiniIDE project folder using a text editor and using "all files" as the option when instructing the text editor to Open a file. The S-Record consists of a sequence of lines, each line starting with a code specifying what is in the line and ending with a code specifying information about lines that follow. I have reproduced the long listing of Figure 2 in MS Word format as shown in Figure 4. In Figure 4, I have highlighted specific instructions (the binary coded part in column 3) in bold with different colors. Those instruction codes are highlighted in bold and the same color in the S-record in Figure 3. The first and last lines of the S-record are used to define the starting point (just after the first line) and the ending point (just before the last line). The second line of the S- record (i.e., S1131000B6101D7A0800CE1030C613B60800A10031) starts with "S113, defining the line as a full line of binary program code. This allows the suffix "31" to be extracted by the HC12 EVB. The specific value "31" of the suffix on this line, "1E" on the third line, and "87" on the fourth line provide information to the program loading software running on the microcontroller. My main interest here is for you to "see" the binary coded instructions in the S-record file. For this purpose, the entries of Figure 3a have been artificially separated (by me in the file listing) to show the instruction components and the memory assignments. The green-colored entries represent the starting address for the program entries in the line. You can see the associations with the colorings in Figures 3 and 4. The starting memory location for the fourth line is given as 1020 hex. You should be able to verify this from the information on line 17 of the long listing. QuickTime™ an d a decompressor are need ed to see this p icture . Figure 2: Screen shot of .lst file giving details of what the assembler did. Reproduced in Figure 4 below as MS Word file. S0030000FC S1131000B6101D7A0800CE1030C613B60800A10031 S11310102C05A6007A0800090431F020FE0103051E S106102006132987 S9030000FC (a) S-Record File S0030000FC S113 1000 B6101D 7A0800 CE1030 C613 B60800 A100 31 S113 1010 2C05 A600 7A0800 09 0431F0 20FE 01 03 05 1E S106 1020 06 13 29 87 S9030000FC (b) My Separation of the entries above to illustrate the components. Figure 3. The S12 file listing. C:\Program Files\MiniIDE\TempSave\as12-example\example.lst - generated by MGTEK Assembler ASM12 V1.26 Build 144 for WIN32 (x86) - Fri Aug 22 12:59:04 2008 1: =00000014 N: equ 20 2: =00000800 org $800 3: 0800 +0001 max_val: rmb 1 4: =00001000 org $1000 5: 1000 B6 101D ldaa array 6: 1003 7A 0800 staa max_val 7: 1006 CE 1030 ldx #arrAY+n-1 8: 1009 C6 13 ldab #N-1 9: 100B B6 0800 loop: ldaa max_val 10: 100E A1 00 cmpa 0,x 11: 1010 2C 05 bge chk_ end 12: 1012 A6 00 ldaa 0,x 13: 1014 7A 0800 staa max_val 14: 1017 09 chk_end: dex 15: 1018 04 31 F0 dbne b,loop 16: 101B 20 FE forever: bra forever 17: 101D 01 03 05 06 13 29 array: db 1,3,5,6,19,41 18: end Symbols: array *0000101d chk_end *00001017 forever *0000101b loop *0000100b max_val *00000800 n *00000014 Figure 4: Word format listing of information in Figure 2. 2. Looking at What The Assembler Did The long listing in Figures 2 and 4 provide you with the details regarding how the assembler converted your English language program (with labels and assembler directives) into the actual binary coded instructions. At the end, under "Symbols", you will see the labels you used when creating the English language program. The label array will be replaced by the value of the starting memory location for line 17, i.e., %101D (I am using "%" to indicate a hexadecimal number). This value was determined when line 17 was encountered by the assembler (i.e., the point when the memory pointer for that line had been set to %101D). The label array is used as the operand of the ldaa instruction in line 5 of the long listing (Figure 4). The binary code for line 5 of the long listing is shown as B6 101D. We will be covering addressing modes early in the course. For this instruction, we are asking that the 8-bit data value stored at the address pointed to by the label array be loaded into the accumulator A register. This is the Extended Addressing Mode discussed on pages 14 and 15 of your textbook. Appendix A of your textbook lists all of the opcodes (English versions) along with the addressing modes that can be used with the given opcode. Check page 645 of your textbook and look at the entry for the LDAA instruction being used in line 5 of the long listing. You will see that "LDAA" can be used with a variety of addressing modes, including the Extended Addressing Mode (abbreviated "Ext" in the Addr. Mode column of the table). The column to the right of "Ext" for the LDAA instruction gives B6 hh ll. Here, "B6" is the binary code for LDAA using the extended addressing mode. "hh" and "ll" represent ("hh") the high-order byte (upper 8 bits) and ("ll") the low order byte (lower 8 bits) ) of the 16 bit memory address. Several microprocessor manufacturers (including Motorola/FreeStyle) use this as the ordering of data. Others use the opposite order (creating the Big Endian/Small Endian problem).1 If the Little Endian format were used instead. the instruction would have been B6 1D10 for address 101D. You can read through the long listing and check your understanding of the replacements of English opcodes and labels with binary codes. In doing this, you can imagine that you had to generate the binary codes directly without the help of an assembler. This is something you probably do not wish to do. 1 This order (high order byte first and lower order byte second as the memory address increases) is called the "Big Endian" format. There are microcontrollers and microprocessors that use the reverse order, with the lower order byte first and the upper order byte second, called the "Little Endian" format. Motorola, for example, has long used the Big Endian format. Intel microprocessors use the Little Endian format. This causes problems when one computer reads a file generated by the other, or when one computer sends a data file to another. In fact, the Internet prescribes the Big Endian format as the required format for data files sent between computers.