External Assembly language Module

advertisement
Mixing External Assembly Module
with HI-Tech C
This is the general format form mixing HI-Tech C with external assembly language modules. You
have to understand the Assembly language used by Hi-Tech C is not exactly the same as the PIC's
assembly--but follows the same principles. ( All externally available variables, labels, and symbols are
first, then the code section designators, and finally, the code in the specified section).
The assembly used by this C compiler uses macros and predefined memory segment labels. To
limit the commenting at this point, I will only describe the sections important to calling externally
defined assembly routines that will to be written in Hi-Tech C's macro assembly language.
The only way to call an externally defined (meaning written in another file) assembly language
subroutine is to make sure that the function label is globally accessible, ensure that HI-Tech C’s
assembly language macro, PSECT, is used to place the assembly coded routine in the correct position in
the final compiled assembly file, and when needed, where to find function elements in memory such as
passed routine parameters, and return function return values in memory so that it functions correctly
with the compiler’s generated code.
In order to know the important memory locations, an understanding of how this compiler sets
up its values in a given C coded modules is important (you have to know how to interpret addresses
seen in a disassembly listing). The assembly language symbols made available by this C compiler are only
available to assembly code written in the same C file; however, you have to know what the symbols are
in order to understand what the addresses mean. You have to plan your code out first then read the
disassembly to figure out where the appropriate addresses are in the assembly code. This is because the
location of a function’s parameter variables and return values can vary depending on globally defined
variables.
To start, parameter values are passed in a section of memory referred to as function parameter
space--if the parameter count is greater than 1 and greater than 8 bits. If the parameter count is 1, and
it is an 8 bit value, the value is passed to the function through WREG. If the parameter count is greater
than 1, and the first parameter is a byte in length, then the 1st parameter is passed into the function
through WREG and the other values are placed in the function area. (There is function parameter space
for each function being called--when it is called. The function parameter space is programmable
accessed using the symbol pattern, ?_<c function name>, where <c function name> is the name of the c
function.
Mixing External Assembly Module
Page 1
Look at the following call to an external function. In this external assembly module, the
function's parameter space starts at ?_Dummy16BitAdd. To get access to the two parameters of the
function, understand that parameter's a and b are both 2 bytes and the PIC's memory bank’s are 8 bits
wide. Because of this, 2 bytes takes up 2 memory slots. The lower byte address is the lower byte of a;
the higher address is the upper byte of a. So, the variable a has memory locations ?_Dummy16BitAdd
set for its lower byte, and ?_Dummy16BitAdd + 1 for variable a's upper byte. Variable b has
?_Dummy16BitAdd + 2 for its lower byte and b's upper byte is at memory location
?_Dummy16BitAdd + 3.
Dummy16BitAdd(15,12);
0040 300F MOVLW 0xf
0041 00A3 MOVWF 0x23
0042 01A4 CLRF 0x24
0043 300C MOVLW 0xc
0044 00A5 MOVWF 0x25
0045 01A6 CLRF 0x26
0046 20D3 CALL 0xd3
In this code snippet from the main function in the main.c file, the call to the external function
Dummy16BitAdd(15,12) has a proto-type of
extern int Dummy16BitAdd(int a, int b).
The extern key word means that this function is defined in another file. In the above disassembly,
the start of the memory set up by the compiler for passed function variables starts at location 0x23.
This is means that ?_Dummy16BitAdd is located at 23H. This also means that variable a' lower byte is
located at 23H, a<15:8> is located at 24H (?_Dummy16BitAdd + 1), b<7:0> is located at 25H
(?_Dummy16BitAdd + 2), and b<15:8> falls to memory location 26H (?_Dummy16BitAdd + 3).
The return value of a function is placed in a memory location sectioned off by the compiler
called btemp (a section no larger than 4 bytes)--if the return value from the function is larger than 1
byte; otherwise, it is returned in WREG. For example, the return value of the function below is greater
than 1 byte, the return value is returned in the memory location set off by the C compiler called btemp.
The lower byte of the return value is at btemp, and the upper byte is at btemp + 1. In order to
determine the memory location of a return value, you have to make up another dummy function and
see where the values are being returned to. The following code snippet explains how to interpret the
disassembly.
Mixing External Assembly Module
Page 2
return 500;
00AC 30F4 MOVLW 0xf4
00AD 00FE MOVWF 0x7e
00AE 3001 MOVLW 0x1
00AF 00FF MOVWF 0x7f
This return statement from a function has the following disassembly that shows that the compiler
has set aside memory locations 7eH (btemp) and 7fH (btemp+1) for a function’s return value usage.
This is the main function that calls the external subroutine.
#include <htc.h>
extern int Dummy16BitAdd(int a, int b);
void main(void)
{
Dummy16BitAdd(15,12);
asm(“SLEEP”);
}
The external routine’s assembly module looks like this.
Mixing External Assembly Module
Page 3
#include <aspic.h> ; Predefined Register symbols here
global _Dummy16BitAdd
ParamStart
a_Start
b_Start
ReturnStart
ReturnLow
ReturnHigh
equ 0x23 /* reading disassembly show this is start of
parameters to function */
equ 0x23 // 16 bit variable a start here
equ 0x25 // 2 byte variable b starts here
equ 0x7e // return addresses start here
equ 0x7e
equ 0x7f
PSECT text0,local,class=CODE,delta=2
_Dummy16BitAdd:
MOVF b_Start, W
ADDWF b_Start
movf b_Start, W
movwf ReturnLow /*return address for return types greater
than 1 byte instead of using WREG */
btfss CARRY
movlw 0
movlw 1
movwf ReturnHigh
Mixing External Assembly Module
Page 4
Download