Assembly language Part 3 (PIC Microcontroller)

Codepage

The codepage directive is used for program code. These directives are here used to define two regions, one for the Reset and Interrupt vectors in between 000h and 004h called vec and the other called program to be used for executable code from 005 h through 3FFh. Notice the use of the prefix 0x to denote the hexadecimal base. This is the notation used in the C language.

Relocatable assembly-level code translation.

Fig. 8.3 Relocatable assembly-level code translation.

Table 8.5: The pic16f84.lkr linker command file.

The pic16f84.lkr linker command file.


Databank

This is similar to codepage but is used for variable data in RAM. Here the file register array between File 0Ch and File 4Fh is called gprs.

section

This linker directive names two code streams. The first called VECTORS will be used by the programmer to store the two vector goto instructions while TEXT is used for the core program code. The source code assembler directive code with the appropriate label tells the linker which stream any following code is to be placed; for example, see Program 8.2. As many code sections from any codepage can be created as desired. For instance, all subroutines may be placed together in Program memory by modifying the linker file thus:

tmp926_thumb[2]_thumb

Sections can be made from DATABANK memory with RAM replacing the ROM attribute. In our case we have not defined a data section and the unlabelled assembler directive udata (Uninitialiized DATA) allows space to be reserved for labels in the general-purpose register array; see Program 8.4.

To illustrate the principle of linking we will implement the mathematical functiontmp927_thumb[2]_thumb, known as root mean square. There are three teams working on this problem.9 Tasks have been allocated by the project manager (a fourth person?) as follows:

1. The main function which sequences the steps:

Linking three source files to implement a root mean square program.

Fig. 8.4 Linking three source files to implement a root mean square program.

(a) Square NUM_1.

(b) Square NUM_2.

(c) Add NUM_12 + NUM_22

(d) Square root item (c).

2. Design of a subroutine to square a byte number in the Working register to give a double-byte outcome in two GPRs.

3. Design of a subroutine to evaluate the square root of a double-byte sum and return it in W.

The process based on this decomposition of the task is shown diagram-matically in Fig. 8.4.

The main function is shown in Program 8.2. The program commences with the Reset goto instruction and is located in the VECTORS code stream. From the MAIN label onwards, code is located in the TEXT code stream using the directive TEXT code. We see from the map file output by the linker in Table 8.6 that MAIN is located at 005 h.

The main routine uses four variables located in general-purpose file. These are placed in uninitialized RAM with the directives udata and res. A single file register is reserved for each of the two input variables NUM_1 and NUM_2 respectively. Two bytes are reserved for SUM which is used to hold the sum NUM_1 + NUM_2. As this is to be the input for the subroutine SQR_ROOT, it is declared global at the end of the file. This means that the location is public, that is additional files that are linked together can use the label SUM by declaring it extern – i.e. external to the file. Variables not declared thus are ‘hidden’ from the outside world, i.e. are private (or local) variables. In this manner the directive extern at the head of Program 8.2 allows the main routine to call the subroutines SQR_ROOT and SQR without knowing in advance where they are. In the same way the variable SQUARE is used by subroutine SQR to return the square of the byte sent to it in W. Space for this is reserved in a GPR in subroutine SQR and its exact whereabouts is not known by main.asm but will be allocated later by the linker. From the map file of Table 8.6 it is finally located in File 11 h.

Program 8.2 The main relocatable source file main.asm.

The main relocatable source file main.asm.

The main body of the code follows the task list enumerated above. The value NUM_12 is placed in file registers SUM:SUM+1 to which the computed NUM_22 is added. The outcome is then used as input to subroutine SQR_ROOT to return the root-mean square byte in W. Finally this is copied to the file register named RMS, for which a single byte has been reserved in the Data stream.

The subroutine sqr.asm of Program 8.3 is based on the subroutine of Program 6.5,which multiplies two byte numbers. In this case on entry the contents of the Working register are copied to a file register labelled X and a 16-bit version constructed in X_COPY_H:X_COPY_L. The shift and add algorithm then evaluates X x X = X2. These three file registers are allocated with the directive udata_ovr (OVeRlay Uninitialized DATA).

Program 8.3 The relocatable source file sqr.asm.

The relocatable source file sqr.asm.

This is similar to udata but indicates to the linker that file registers allocated in this way can be reused by other modules. In the map file of Table 8.6 we see that X has been allocated File 13h as has I, a variable in subroutine SQR_ROOT – see Program 8.3. This makes more efficient use of available Data memory. Variables that are only alive within the subroutine that they are declared in are known in the C language as automatic, as their space is automatically reallocated as needed. The situation where variable space is preserved is known as static. Global variables, such as SQUARE are always static. In this case the variable SQUARE is created by reserving two bytes using the udata directive. It is also published using the global directive, as is the name of the subroutine.

Program 8.4 The relocatable source file root2.asm.

The relocatable source file root2.asm.

The final source file of the trio is the subroutine coded in Program 8.4. This is virtually identical to the absolute equivalent described in Program 8.1. Comparing the two, the org directive has been replaced by TEXT code and cblock by udata_ovr for the automatic local data. The data is passed to the subroutine SQR_ROOT via the external 2-byte global variable SUM, space for which has been allocated in main.asm. The subroutine name SQR_ROOT is published as global to make it visible to main.asm.

Like all source files, root2.asm makes use of SPRs such as STATUS. For this reason the file p16f84.inc of Table 8.4 has been included at the head of the file. As this file comprises a set of equ directives, the names thus published are absolute and are not allocated or changed in any way by the linker. Thus the linker map of Table 8.6 does not list such fixed symbols. They are, however, enumerated in the listing file produced by the linker.

In order to link the three source files together, the linker program must be given a command line listing the names of the input object files output by the relocatable assembler, the linker command file and the names of the output map and machine-code file. In the case of our example this was:

tmp932_thumb[2]_thumb

which names the output map file rms.map and the absolute machine-code file rms.hex.

For documentation purposes the linker generates a composite listing file, similar (but more comprehensive) to that of Table 8.1 and an optional map file. The map file of Table 8.6 shows two lists. The first displays information for each section. This includes its name, type, start address, whether the section resides in Program or Data memory and its size in bytes. The Program Memory Usage table shows that 62 bytes of Program memory is used, including the two bytes of the Reset vector goto instruction, or around 6% of the possible total.

The second table shows information about the symbols in the composite program. Each symbol’s location in either the Program or Data store is given together with the source file where it is defined. Global symbols are noted as extern. Local variables are all labelled static, including automatic reusable variables such as COUNT and X_COPY_H both at File 15h.

The final outcome, shown in Table 8.7, is a normal executable machine code file. The format of this file is exactly as described for Table 8.2 and can be loaded into absolute Program memory and run in the normal way.

Table 8.6: The output linker map file rms.asm.

The output linker map file rms.asm.

Developing, testing and debugging software requires a large number of software tools, many of which we have discussed earlier, such as an editor, assembler and linker. In practice there are many other tools such as high-level language compilers (see topic 9), simulators and EPROM programmers; shown diagrammatically in Fig. 8.5. Setting up these tools and interacting on an individual basis can be quite complex, especially where products from various manufacturers are involved. In this latter case, ensuring compatibility between the various intermediate file formats can be a nightmare.

Table 8.7: The resulting absolute object file rms.hex.

Code building and testing tools.

Fig. 8.5 Code building and testing tools.

Many software houses designing code development tools provide a graphical environment which integrates and sequences the process in a logical and easy to use manner. Of relevance to the PIC family, Microchip Technology provides a Microsoft Windows-based Integrated Development Environment (IDE) which brings all compatible code development tools under one roof, called MPLAB. Like all Microchip software tools (except C compilers) MPLAB is supplied free of charge.

MPLAB integrates Microchip-compatible tools to form a complete software development environment. Among its features are:

• A project manager which groups the specific files related to a project; for example, source, object, simulator, listing and hex files.

• An editor to create source files and linker script files.

• An assembler, linker and librarian to translate source code and create libraries of code, which can be used with the linker without leaving the IDE.

• A simulator to model the instruction execution and I/O on the PC.

• A downloader to work in conjunction with device programmers via the PC’s serial port – see Fig. 16.4.

• In-circuit emulation software to emulate PIC MCUs in real time in the target hardware. This is accomplished by driving an In-Circuit Emulator (ICE)10 via the PC’s serial or parallel port, replacing the target PIC.

The Microchip manual MPLAB IDE, Simulator, Editor User’s Guide gives a MPLAB tutorial and reference details, which are beyond the scope of this topic. However, for illustrative purposes two screen shots taken during the development of our previous example linking main.asm, sqr.asm and root2.asm are reproduced in Figs. 8.6 and 8.7.

Figure 8.6 shows the project called example.pjt being set up. In the Files window the three source files, which have already been created using the editor, are specified as is the name of the linker script file pic16f84.lkr which has also been previously created and saved. The resulting machine-code file is named rms.hex.

Once the project is set up in this manner, the sequence of operations, namely:

1. Assemble main.asm to give main.o.

2. Assemble sqr.asm to give sqr.o.

3. Assemble root2.asm to give root2.o.

4. Using pic16f84.lkr to link together object files 1, 2 and 3.

5. If no syntax errors, create the absolute executable file of Table 8.7.

Can be initiated by choosing from the Project menu (top second left in Fig. 8.7) Make Project. If there are syntax errors an Error window will appear listing errors. Double clicking on any specific error will bring up the relevant Source window with the line in question highlighted.

Next post:

Previous post: