ARM C and Assembly Mixed Programming and Examples

xiaoxiao2021-03-06  58

In embedded system development, the primary programming language currently used is C and assembly, C already has a corresponding compiler, but now is still relatively small. In slightly large-scale embedded software, such as containing OS, most of the code is written in c, mainly because the structure of the C language is better, easy to understand, and there are a large number of support libraries. Despite this, many places should also be used in assembly language, such as the initialization of the hardware system, including the setting of the CPU state, the interrupt enable, the main frequency setting, and the control parameters of the RAM and initialization, some interrupt processing It is also possible to compile. Another place to use compilation is some code blocks that are very sensitive to performance. This is not to rely on the generation code of the C compiler, and to manually prepare assembly to achieve optimization purposes. Moreover, the assembly language is closely linked to the CPU's instruction set, as an embedded system development involving the underlying, the use of proficient corresponding assembly languages ​​is also necessary.

Simply C or Assembly Programming Refer to the related books or manuals, which mainly discusses mixed programming of C and assembly, including function calls between each other. The following is a discussion, and C is not involved.

1. Compilation in C language

The compilation instructions embedded in C include most of the ARM and Thumb instructions, but it is somewhat different from the instructions in the assembly file, there are some limits, mainly including the following aspects:

a. You cannot assign a value directly to the PC register, and the program jumps to use B or BL instructions.

b. Do not use too complicated C expressions when using physical registers, avoid physical registers conflicts

c. R12 and R13 may be used by the compiler to store the intermediate compilation result, calculate the R0 to R3, R12, and R14 for sub-program calls, so avoid directly using these physical registers.

d. Do not specify the physical register directly, and the compiler is allocated

The label used in embedded assembly is __ASM or ASM keyword, the usage is as follows:

__ASM

{

Instruction [; instruction]

...

[instruction]

}

ASM ("Instruction [; Instruction]);

By following an example, explain how to embed 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!";

Char B [64];

MY_STRCPY (A, B);

Printf ("Original:% S", A);

Printf ("Copyed:% S", B);

Return 0;

}

The value transmitted between C and assembly here is implemented with a pointer of C, because the pointer corresponds to the address, so it can be accessed in the assembly.

2. Global variables defined in assembly

The embedded assembly does not have to edit the assembly language file separately, which is relatively simple, but there are many restrictions, when the compilation code is usually placed in a separate assembly file. At this time, you need to pass some data between assembly and C, the easiest way is to use global variables.

/ * Cfile.c

* Define global variables and as a master program

* /

#include int gvar_1 = 12;

Extern asmdouble (void);

int main ()

{

Printf ("Original Value Of GVAR_1 IS:% D", GVAR_1);

askDOUBLE ();

Printf ("Modified Value Of GVAR_1 IS:% D", GVAR_1);

Return 0;

}

Corresponding assembly language file

Called by main (in c), to double an integer, a global var defined IN C is for.

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. Call the compilation function in C

In C. Call the function in the assembly file, there are two main work to be done, one is declared in C, plus the extern keyword; Second, use the export export function name in the assembly, and use the function name as The identifier of the assembly code segment, finally returned with MOV PC, LR. Then, the function can be used in C. From the angle from C, it does not know that the implementation of the function is to use C or compile. A deeper cause is because C's function names indicate that the function code start address is left, this and the assembly Label are consistent.

/ * 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 IncrementAfter Read

CMP R4, # 0

BEQ over

STRB R4, [R1], # 1

b loop

Over

MOV PC, LR

End

Here, parameter transmission between C and assembly is performed by the provisions of ATPCS (ARM Thumb Procedure Call Standard). Simply put, if the function is not more than four parameters, the corresponding use of R0-R3 is transmitted, more than 4, with the stack, and the return value of the function is returned by R0.

4. Call C function in assembly

Call C in the assembly, you need to correspond to the C function name corresponding to the IMPORT in the assembly, and then put the C code in a separate C file to compile, and the remaining work is processed by the connector. The details of parameters Transfer comes from atpcs

; if there is 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, caled by asmfile * /

Int cfun (int A, int B, int C)

{

RETURN A B C;

}

The function of calling C in the assembly, the passage of the parameters is also implemented by ATPCS. It should be pointed out that when the number of parameters of the function is greater than 4, you should use the STACK, specifically see the ATPCS specification.

summary

The above is demonstrated by several simple examples to demonstrate some of the methods and basic ideas commonly used in embedded development. In fact, the core problem is how to pass the value between C and assembly. The remaining problems are their respective Treatment with your own way. The above is just a throwing jade, more detailed and complex usage methods to combine practical applications and refer to relevant information.

Description

The above code is compiled in the engineering of ADS 1.2 and passes the software simulation in the corresponding AXD.

Reference

1. Du Chunlei, ARM Architecture and Programming, Tsinghua University Press, 2003

2. Associated startup code for UC / OS-II for ARM transplant

转载请注明原文地址:https://www.9cbs.com/read-118436.html

New Post(0)