Common usage and examples of static keywords in C Language
In embedded system development Programming Language Is C and assembly,
C ++ already has a corresponding compiler, but it is still rarely used. In a slightly larger
In large-scale embedded software, such as operating systems, most Code Both use C encoding.
The main reason is that the C language structure is good, which is easy for people to understand.
A large number of supported libraries. However, assembly languages are still used in many places, such
Hardware system initialization at startup, including CPU status setting, interrupt enabling,
Clock speed setting, Ram control parameters and initialization, and some interrupt handlers
It may also involve assembly. Another place to use assembly is the non-performance
This is a sensitive code block. Instead of relying on the C compiler to generate code, you must manually
Compile the compilation to achieve the goal of optimization. In addition, the Assembly Language is the instruction set with the CPU
Closely connected, developed as an embedded system involving the underlying layer, skilled in corresponding Assembly Language
It is also required.
For simple C or assembly programming, refer to relevant books or manuals.
On the mixed programming of C and assembly, including function calls between them. There are four types:
C ++ is not involved.
1. Embedded Assembly in C Language
The Assembly commands embedded in C contain most arm and thumb commands,
The usage is somewhat different from the commands in the Assembly file, and there are some restrictions, mainly including the following
Several aspects:
A. You cannot assign values directly to the PC register, Program Use B or bl commands to redirect
B. Do not use overly complex C expressions when using physical registers to avoid physical register conflicts.
C. R12 and R13 may be used by the compiler to store intermediate compilation results. When calculating expression values, R0 to R3, R12, and R14 may be used for subroutine calls. Therefore, avoid directly using these physical registers.
D. Generally, do not directly specify physical registers for the compiler to allocate.
The marker used for Embedded Assembly is the _ ASM or ASM keyword. The usage is as follows:
_ ASM
{
Instruction [; instruction]
...
[Instruction]
}
ASM ("Instruction [; instruction]");
The following example shows how to embed the Assembly Language in C,
# Include <stdio. h>
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", );
Printf ("copyed: % s", B );
Return 0;
}
Here, the value transfer between C and assembly is implemented using the pointer of C, because the pointer
It corresponds to the address, so it can also be accessed in the Assembly.
2. Use global variables defined by C in assembly
Embedded Assembly does not require independent editing of assembly language files, which is concise, but has many limitations.
When the Assembly Code is large, it is generally placed in a separate Assembly file. In this case
The easiest way to transfer data between Assembly and C is to use
Global variable.
/* Cfile. c
* Defines global variables and serves as the main program
*/
# Include <stdio. h>
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 file
; 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. Call the compiled function in C.
Calling functions in assembly files in C involves two main tasks:
Declare the function prototype in C and add the extern keyword. Second, it is used in assembly.
Export exports the function name and uses this function name as the identifier of the assembly code segment.
Then return with mov PC and LR. Then, you can use this function in C. Slave
From the perspective of C, I don't know whether the function is implemented in C or assembly. Deeper reasons
It is because the function name of C indicates the start address of the function code.
The labels are consistent.
/* Cfile. c
* In C, call an ASM function, asm_strcpy
* Sep 9, 2004
*/
# Include <stdio. h>
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
Here, the parameter transfer between C and assembly is through atpcs (ARM
Thumb procedure call standard. Simply put
Is if the function has no more than four parameters, corresponding to the use of R0-R3 to pass, multiple
With the help of stacks, function return values are returned through R0.
4. Call the C function in the Assembly.
To call a C function in an assembly, you must import the corresponding C function name in the Assembly.
And then put the C code in an independent C file for compilation.
Is processed 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;
}
Call the C function in the Assembly. The parameter transmission is also implemented through atpcs.
. It must be noted that when the number of parameters of a function is greater than 4, the use of stack
See atpcs specifications