Presentation is loading. Please wait.

Presentation is loading. Please wait.

Mixing C and ASM Programs

Similar presentations


Presentation on theme: "Mixing C and ASM Programs"— Presentation transcript:

1 Mixing C and ASM Programs
Note: the following slides have been created from information found in the CodeWarrior Help System under the heading: Help – Search - Mixed C and Assembler Applications HC12 Assembler Often time-critical routines are written in Assembly Language, and the rest of the software is written in C, thus a “mixed Assembly and C” project must be created. 4/13/2018 Mixing C and Assembly

2 When you intend to mix Assembly source file and ANSI-C source files in a single application, the following issues are important: Memory models Parameter passing scheme Return Value Accessing assembly variables in an ANSI-C source file  Accessing ANSI-C variables in an assembly source file Invoking an assembly function in an ANSI-C source file Support for structured types  4/13/2018 Mixing C and Assembly

3 To build mixed C and Assembler applications, you have to know how the C Compiler uses registers and calls procedures. The following sections will describe this for compatibility with the compiler. Parameter passing conventions differ somewhat between different ANSI-C compilers. The information presented here is solely for the CodeWarrior HC12 Compiler. To build mixed C 4/13/2018 Mixing C and Assembly

4 Memory models The memory models are only important if you mix C and assembly code. In this case all sources must be compiled or assembled with the same memory model. The Assembler supports all memory models of the compiler. Depending on your hardware, use the smallest memory model suitable for your programming needs. The following slide summarizes the different memory models. It shows when to use a particular memory model and which assembler switch to use. 4/13/2018 Mixing C and Assembly

5 Memory Models Small Memory Model (Assembler option –Ms) Used for applications that fit into 64 kbyte address space. Banked Memory Model (Option –Mb) Used for larger applications whose code does not fit into 64 kbyte address space, but whose data does fit in 64 k space. Large Memory Model (Option –ML) Used for applications whose code and data do not fit into 64 k address spaces. 4/13/2018 Mixing C and Assembly

6 We shall use only the small memory model in this course.
4/13/2018 Mixing C and Assembly

7 Parameter Passing Scheme
When you are using the HC12 compiler, the parameter passing scheme is the following: The “PASCAL calling convention” is used for functions with a fixed number of parameters: The caller pushes the arguments from left to right. After returning from the call, the caller must remove the parameters from the stack. 4/13/2018 Mixing C and Assembly

8 (The “C calling convention” is used only for functions with a variable number of parameters. In this convention the caller pushes the arguments from right to left.) With either PASCAL or C convention, if the last parameter of a function with a fixed number of arguments has a simple type, it is not pushed but is instead passed in a register. This results in shorter code because pushing the last parameter can be avoided. Table 11.2 shows an overview of the registers used for argument passing 4/13/2018 Mixing C and Assembly

9 Table 11.2 Registers used for passing the last argument to a function
Size of return value Type example Register 1 byte char B 2 bytes int D 3 bytes far data pointer X(L), B(H) 4 bytes long D(L), X(H) Parameters having a type not listed are passed on the stack (i.e., all those having a size greater than 4 bytes). 4/13/2018 Mixing C and Assembly

10 Passsing back the return value
Function results usually are returned in registers, except if the function returns a result larger than 4 bytes (see Table 11.3). Depending on the size of the return type, the following different registers are used: 4/13/2018 Mixing C and Assembly

11 Table 11.3 Data type and registers used in function returns
Size of return value Type example Register 1 byte char B 2 bytes int D 3 bytes far data pointer X(L), B(H) 4 bytes long D(L), X(H) Functions returning a result larger than two words are called with an additional parameter. This parameter is the address where the result should get copied to. 4/13/2018 Mixing C and Assembly

12 Accessing assembly variables from inside an ANSI-C source file
A variable or constant defined in an assembly source file is accessible in an ANSI-C source file. The variable or constant is defined in the assembly source file using the standard assembly syntax. Variables and constants must be exported using the XDEF directive to make them visible from other modules (Listing 11.1). 4/13/2018 Mixing C and Assembly

13 Listing 11.1 Example of data and constant definition
inside an assembly routine that is accessible to other C or assembly modules. (XDEF “exports” these data and constant definitions to make them accessible to other modules.)            XDEF  ASMData, ASMConst DataSec:   SECTION ASMData:   DS.W  1      ; Definition of a variable ConstSec: SECTION ASMConst: DC.W  $44A6  ; Definition of a constant 4/13/2018 Mixing C and Assembly

14 We recommend that you generate a header file for each assembler source file.
This header file should contain the interface (function prototype declarations) for all of the routines in the assembly module that you want to allow other program modules to have access to. An “external declaration” (via the extern statement) for the variable or constant may also be inserted in the header file (Listing 11.2). 4/13/2018 Mixing C and Assembly

15 Listing 11. 2 Example of data and constant declarations
Listing Example of data and constant declarations that must be made in the C program in order to be able to access the data and constants defined in the assembly program. /* External declaration of a variable */ extern int       ASMData; /* External declaration of a constant */ extern const int ASMConst; (These 2 “extern” declarations may be put into a header (*.h) file that can be easily included at the beginning of each C or assembly program that refers to either of these locations.) The variables or constants defined in the assembly module can then be accessed in the C program in the usual way, using their names, as shown below: ASMData = ASMConst + 3; 4/13/2018 Mixing C and Assembly

16 Accessing ANSI-C variables from inside an assembly source file
A variable or constant defined in an ANSI-C source file is accessible in an assembly source file. The variable or constant is defined in the ANSI-C source file using the standard ANSI-C syntax (Listing 11.4). 4/13/2018 Mixing C and Assembly

17 Listing 11.4 Example definition of data and constants defined in the C program unsigned int CData;     /* Definition of a variable */ unsigned const int CConst; /*Defn of a constant */ 4/13/2018 Mixing C and Assembly

18 An external declaration for the variable or constant must be inserted into the assembly source file (Listing 11.5). This can also be done in a separate “header” (*.h) file, which is then included in the assembly source file. 4/13/2018 Mixing C and Assembly

19 XREF CData; External declaration of variable
Listing 11.5 Example declaration of external data and constants in the assembly program which were allocated in the C program: XREF CData;  External declaration of variable      XREF CConst; External declaration of a constant The variables or constants can then be accessed in the usual way, simply by using their names (Listing 11.6). 4/13/2018 Mixing C and Assembly

20 Listing 11.6 Example showing how a data variable and a data constant that were declared in a C program may be accessed in an assembly module.            LDD CConst           ....             LDD CData            .... 4/13/2018 Mixing C and Assembly

21 Invoking an assembly function from inside an ANSI-C source file
A function implemented in an assembly source file (mixasm.asm in Listing 11.7) can be invoked in a C source file (Listing 11.9). During the implementation of the function in the assembly source file, you should pay attention to the parameter passing scheme of the ANSI-C compiler you are using in order to retrieve the parameter from the right place. 4/13/2018 Mixing C and Assembly

22 Listing 11.7 Example of an assembly file: mixasm.asm
         XREF  CData     ;This progam imports (references) variable “Cdata” ;that was declared in the C program module.          XDEF  AddVar       ;Entry point of ASM subroutine exported, so other ;separately compiled program modules can reference it.        XDEF  ASMData ;ASMData symbol is exported, so other separately ;compiled programs can reference it. DataSec:    SECTION ASMData:    DS.B  1 CodeSec:    SECTION AddVar:        ;This subroutine adds the input argument (passed in register B) ` ; to the global variable CData that was defined in the external C ; program.      ADDB  CData     ; Add CData to the input parameter in reg B              STAB  ASMData ;result of addition put in ;ASMData location.          RTS 4/13/2018 Mixing C and Assembly

23 Function prototype statements are needed at the top of each program module, listing each function that will be called by that module. Recall that function prototype statements define the “software interface” to the subroutine or function. This includes the function name, the number and order of input arguments and their data types, and what data type is returned, if any. Example of a function prototype for a function named “MyFunction” that accepts an integer, a character, and a long integer, and returns an integer value: int MyFunction(int, char, long int); In large software projects, it is common practice to include one or more header (*.h) files at the top of each program module. These header file(s) include the function prototype for each function that is called by that module. A header file often contains function prototypes for a large number of related functions, but only a few of these functions may be called by a specific module. Listing 11.8 contains the header file for the assembly language function module “mixasm.asm” that is shown in Listing Note in Listing 11.9 how this header file can be put at the top of a C program “mixc.c” that calls module mixasm.asm. Note that the #include “mixasm.h” statement could be replaced by the function prototype statement “void AddVar(unsigned char);” 4/13/2018 Mixing C and Assembly

24 Listing 11.8 Header file for the assembly mixasm.asm file: mixasm.h
/* mixasm.h */ #ifndef _MIXASM_H_ #define _MIXASM_H_ void AddVar(unsigned char); /* This is a function prototype statement that declares an external subroutine that receives one unsigned character input argument and returns no value. function that adds the parameter value to global CData and then stores the result in ASMData variable which receives the result of AddVar */ extern char ASMData; #endif /* _MIXASM_H_ */ The function can then be invoked in the usual way, by using its name. 4/13/2018 Mixing C and Assembly

25 Example of a C file C source code file (mixc.c) has the main() function which calls the AddVar() function. See Listing 11.9. 4/13/2018 Mixing C and Assembly

26 Listing 11.9 Example C source code file: mixc.c
static int Error          = 0; const unsigned char CData = 12; #include "mixasm.h" void main(void) {    AddVar(10);    if (ASMData != CData + 10){      Error = 1;    } else {     Error = 0;   }    for(;;); // wait forever 4/13/2018 Mixing C and Assembly

27 NOTE: Be careful, the assembler will not make any checks on the number and type of the function parameters. 4/13/2018 Mixing C and Assembly

28 Linker Parameter (.prm) File
The application must be correctly linked. For these C and *.asm files, a possible linker parameter file is shown in Listing 4/13/2018 Mixing C and Assembly

29 Listing 11.10 Example of linker parameter file: mixasm.prm
LINK mixasm.abs NAMES    mixc.o mixasm.o END SECTIONS    MY_ROM=READ_ONLY  0x4000 TO 0x7FFF;    MY_RAM   = READ_WRITE 0x400 TO 0xFFF;    MY_STACK = READ_WRITE 0xF00 TO 0xFFF; PLACEMENT    DEFAULT_RAM    INTO MY_RAM;    DEFAULT_ROM    INTO MY_ROM;    SSTACK         INTO MY_STACK; INIT main 4/13/2018 Mixing C and Assembly

30 Complete Example of a C program calling an assembly program using HC(S)12 CodeWarrior
4/13/2018 Mixing C and Assembly

31 Enter Project name and desired path Click OK and Next
Procedure: First open CodeWarrior, and click File – New – HC(S)12 New Project Wizard Enter Project name and desired path Click OK and Next Enter MC9S12C128 and Next Check BOTH C and Assembly and Next Check NO to Processor Expert and Next 4/13/2018 Mixing C and Assembly

32 Check NO PC-lint and Next Check ANSI startup code and Next
Check None for floating point and Next Check Small for memory model Check both “Full-Chip Simulation” and also “P&E Multilink/Cyclone Pro” and Finish Once the “mixed C and assembly” project is created, click on “PRM”. Then select (double left click on) the “P&E Multilink/Cyclone Pro” linker parameter file. 4/13/2018 Mixing C and Assembly

33 Examine this file. You will find it to be quite similar to the linker parameter file from Lecture 6 (Linking Relocatable Assembly Modules). Note that if you were using interrupts, you would have to add additional vector initialization statements, as explained in Lecture 6. 4/13/2018 Mixing C and Assembly

34 Repeat this procedure for the “Full-Chip Simulation Linker Parameter file”
4/13/2018 Mixing C and Assembly

35 Now click on the “main.c” file so that it is displayed in the right window. Erase the sample file that was automatically generated, and enter the following example C-language code: 4/13/2018 Mixing C and Assembly

36 #include <hidef.h> /* common defines and macros */
#include <mc9s12c128.h> /* derivative information */ #pragma LINK_INFO DERIVATIVE "mc9s12c128" #include "main_asm.h" /* interface to the assembly module */ int xx,yy,zz,ww ; /* variables defined outside of main function so they are global variables stored in dedicated RAM locations, */ void main(void) { EnableInterrupts; /* This is a built-in macro that executes CLI” */ xx=0x0017; yy=0x0009; zz = asm_main(xx,yy,&ww); /* call the assembly function */ zz=zz+1; ww=ww+2; for(;;) {} /* wait forever */ /* at the end of this program, xx = 0x17, yy = 0x09, zz = 0x21, ww = 0x42 */ } 4/13/2018 Mixing C and Assembly

37 Now click on the “main.asm” file so that it is displayed in the right window. Erase the sample file that was automatically generated, and enter the following example assembly-language code: 4/13/2018 Mixing C and Assembly

38 ; we always export the starting address of the,
; export symbols XDEF asm_main ; we always export the starting address of the, ; assembly function “asm_main”. This allows us to ; reference 'Entry' either in the linker .prm file ; or from another C or assembly language module. INCLUDE 'mc9s12c128.inc' ; variable/data section MY_EXTENDED_RAM: SECTION temp: DS.W 1 ; code section MyCode: SECTION ;************************************************************************** ; Parameter transfer between C and assembly for MetroWerks HCS12 C Compiler: ; In the MAIN.C program,this assembly function is called: ; ; zz = asm_main(xx,yy,&ww); ; Note that xx,yy,and ww are integer variables. ; The leftmost argument (in this case, xx) is pushed on the stack first ; The next argument (in this case, yy) is pushed on the stack. ; This process is repeated, working from left to right until the final ; (rightmost) input argument is reached. However, the rightmost argument is NOT pushed. ; The rightmost argument (in this case, &ww, the address of variable “ww”) is left in the D ; register in order to make the program execute faster. Then as the subroutine ; asm_main is called via a JSR instruction, the return address (PC) gets pushed ; on the stack. 4/13/2018 Mixing C and Assembly

39 Stack Map (once inside the main_asm subroutine)
xx(low) 4,sp-> xx(high) yy(low) 2,sp-> yy(high) (&ww is NOT pushed, but kept in D) pc(low) sp -> pc(high) (return address) 4/13/2018 Mixing C and Assembly

40 ; Therefore, in this example, from inside the asm_main subroutine,
; xx is passed on the stack at “4,sp”. Likewise yy is passed on the stack ; at “2,sp”. Finally, &ww, the address of variable ww, is passed in the D register, ; since it is the final arg. The asm_main program must return the int value of the ; function in register D (= x+y). (If the function were to return a char (8-bit) ; value, it would have to do so in register B,) The address passed as the ; rightmost argument must be written to with the result (= 2*(x+y)). After ; returning from the assembly program "asm_main" to the C program "main.c", ; The calling C program must clean the input arguments off of ; the stack. Because the rightmost input argument was not passed on the ; stack, there are only 2 x 2 = 4 bytes to be cleaned off of the stack, ; so the C compiler inserts an LEAS 4,SP instruction immediately after ; the JSR to "asm_main". ;****************************************************************************/ asm_main: tfr d,x ;x points to address of RAM location "ww" ldd 4,sp ;get leftmost input argument off stack (xx) addd 2,sp ;add it to next input argument (yy) std temp ;store (x+y) result in RAM location "temp" asld ;write 2*(x+y) to addr passed as 3rd arg (&w) std 0,x ldd temp ; return output value of function (= x+y) in register D RTS ; return to calling C program 4/13/2018 Mixing C and Assembly

41 Finally, modify the function prototype statement in the main_asm
Finally, modify the function prototype statement in the main_asm.h file #ifndef _MAIN_ASM_H #define _MAIN_ASM_H #ifdef __cplusplus extern "C" { /* our assembly functions have C calling convention */ #endif int asm_main(int,int,int *); /* interface to my assembly main function */ } #endif /* _MAIN_ASM_H */ 4/13/2018 Mixing C and Assembly


Download ppt "Mixing C and ASM Programs"

Similar presentations


Ads by Google