In the development of embedded system, the main programming languages used at present are C and assembly. C++ has the corresponding compiler, but it is still less used. In larger embedded software, such as OS, most of the code is written in C, mainly because of the C language structure comparisonGood, easy for people to understand, and there are plenty of supporting libraries. Nevertheless, assembly language is still used in many places, such as initialization of hardware system at boot time, including setting CPU status, interrupt enabling, frequency setting, RAM control parameters and initialization, and some interrupt processing aspects are also available.It can involve compilation. Another place to use assembly is some very performance-sensitive code blocks, which can not rely on the C compiler to generate code, but to manually write assembly to achieve optimization purposes. Moreover, assembly language is closely related to the instruction set of CPU, as an embedded system involving the bottom layer.Development, proficiency in the use of assembly language is also necessary. Simple C or assembly programming refers to related books or manuals, where the main discussion of C and assembly mixed programming, including function calls between each other. There are four kinds of situations to be discussed below, which will not involve C++.
1. Embedded assembler in C language
The assembler instructions embedded in C contain most of the ARM and Thumb instructions, but their usage is somewhat different from the instructions in assembler files. There are some limitations, mainly in the following aspects:
a. You can not assign value to the PC register directly, the program jumps to use B or BL instruction.
b. When using physical registers, do not use too complex C expressions to avoid physical register conflicts.
c. R12And R13 may be used by the compiler to hold intermediate compilation results, and R0 to R3, R12, and R14 may be used for subroutine calls when evaluating expression values, so avoid using these physical registers directly
d. Generally, instead of specifying the physical register directly, the tag used to assign the built-in assembly to the compiler is either the AM or the am keyword.
The usage is as follows: __asm {instruction [; instruction]… [instruction]} ASM (“instruction [[instruction]]”);
Here is an example to illustrate how to assemble assembly language in C.
#include void my_strcpy(const char *src, char *dest)
{
char ch;
__asm { loop: ldrb ch, [src], #1 strb ch, [dest], #1 cmp ch, #0 bne loop } }
int main()
{
char *a = “forget it and move on!”;
char b[64];
my_strcpy(a, b);
printf(“original: %s”, a);
printf(“copyed: %s”, b);
return 0;
} In this case, the value transfer between C and assembly is implemented with a pointer to C, which is accessible in assembly because the pointer corresponds to the address.
2. Use global variables defined in C in assembler
Embedded assembly does not need to edit assembly language files separately, it is more concise, but there are many limitations, when the assembly code is more often placed in a separate assembly file. At this point, you need to transfer some data between assembly and C, the simplest way is to use global variables.
/* cfile.c * Define global variables and use them as keynote programs * /
#include
int gVar_1 = 12;
extern asmDouble(void);
int main()
{
printf(“original value of gVar_1 is: %d”,
gVar_1);
asmDouble();
printf(” modified value of gVar_1 is: %d”, gVar_1);
return 0;
}
Corresponding assembly language files;
called by main(in C),
to double an integer,
a global var defined in C is used.
AREA asmfile,
CODE,
READONLY EXPORT asmDouble IMPORT gVar_1 asmDouble ldr r0,
=gVar_1 ldr r1,
[r0] mov r2, #2
mul r3, r1, r2 str r3, [r0] mov pc, lr END
/* cfile.c * Define global variables and use them as keynote programs * /
#include
int gVar_1 = 12;
extern asmDouble(void);
int main()
{
printf(“original value of gVar_1 is: %d”,
gVar_1);
asmDouble();
printf(” modified value of gVar_1 is: %d”, gVar_1);
return 0;
}
Corresponding assembly language files;
called by main(in C),
to double an integer,
a global var defined in C is used.
AREA asmfile,
CODE,
READONLY EXPORT asmDouble IMPORT gVar_1 asmDouble ldr r0,
=gVar_1 ldr r1,
[r0] mov r2, #2
mul r3, r1, r2 str r3, [r0] mov pc, lr END
3. Calling assembly functions in C
There are two main tasks to be done in calling function in assembly file in C.
First, declare the function prototype in C and add the extern keyword.
The second is to use EXPORT to export the function name in assembly, and use the function name as the identification of assembly code segment, and finally return with mov pc, lr. Then you can use this function in C. From the perspective of C, it is not known whether the implementation of the function is C or assembler. The deeper reason is thatThe function name of C plays the role of indicating the starting address of function code.,This is consistent with the label of the assembler.
/* cfile.c * in C,call an asm function, asm_strcpy * Sep 9, 2004 */
#include
extern void asm_strcpy(const char *src, char *dest);
int main() { const char *s = “seasons in the sun”; char d[32]; asm_strcpy(s, d); printf(“source: %s”, s); printf(” destination: %s”,d); return 0; } ;asm function implementation AREA asmfile, CODE, READONLY EXPORT asm_strcpy asm_strcpy loop ldrb r4, [r0], #1 ;address increment after read cmp r4, #0 beq over strb r4, [r1], #1 b loop over mov pc, lr END In this case, parameter passing between C and assembly is done through the ATPCS (ARM Thumb Procedure Call Standard).Simply put, if the function has more than four parameters, the corresponding R0-R3 to pass, more than four with the stack, the return value of the function through R0 to return。
4. Call the function of C in the assembly.
You need the C function name corresponding to IMPORT in the assembly, then you compile the C code in a separate C file, and the rest of the work is handled by the connector。 ;the details of parameters transfer comes from ATPCS ;if there are more than 4 args, stack will be used EXPORT asmfile AREA asmfile, CODE, READONLY IMPORT cFun ENTRY mov r0, #11 mov r1, #22 mov r2, #33 BL cFun END /*C file, called by asmfile */ int cFun(int a, int b, int c) { return a + b + c; } The function of C is invoked in the assembly, and the transfer of parameters is also achieved through ATPCS.It should be pointed out that when the number of parameters of a function is greater than 4, stack is needed.,See ATPCS specification. Summarize the above through a few simple examples to demonstrate some common embedded development C and assembly hybrid programming methods and basic ideas, in fact, the core problem is how to transfer values between C and assembly, the remaining problem is to use their own way to deal with each other.. Above is just throwing bricks to attract jade, more detailed and complex use methods should be combined with practical application and reference to relevant information. The above code is compiled in the engineering of ADS 1.2, and the software is simulated in the corresponding AXD.
The above content is transferred from https://blog.csdn.net/uruita/article/details/7496929 to facilitate future review.