Parameter transfer in C and assembler mixed programming in arm

Source: Internet
Author: User
Tags mixed

C Assembly call each other

For the ARM system, calls between functions written in different languages (mix calls) follow the Atpcs (arm-thumb Procedure call Standard), and atpcs mainly defines the rules for passing parameters when function calls and how to return them from the function. For more information about atpcs you can view the ADS1.2
Online books--developer Guide Section 2.1. What this document is going to say is,
How the parameter is passed in the assembly code for the C function call and how to return it correctly from the C function.
Unlike the x86 parameter transfer rules, Atpcs suggests that the formal parameters of the function are not more than 4, and if the number of formal parameters is less than or equal to 4, the parameters are passed by the R0,R1,R2,R3 four registers; If the number of formal parameters is greater than 4, parts greater than 4 must be passed through the stack.
Let's first discuss the case of a parameter number 4.
Example 1:
Test_asm_args.asm
//--------------------------------------------------------------------------------
IMPORT Test_c_args; Declare Test_c_args function
Area test_asm, CODE, READONLY
EXPORT Test_asm_args
Test_asm_args
STR LR, [sp, #-4]!; Save current LR
LDR r0,=0x10; parameter 1
LDR r1,=0x20; parameter 2
LDR r2,=0x30; parameter 3
LDR r3,=0x40; parameter 4
BL Test_c_args; call C function
LDR pc, [sp], #4; load LR into PC (return main function)
End
Test_c_args.c
//--------------------------------------------------------------------------------
void Test_c_args (int a,int b,int c,int D)
{
PRINTK ("test_c_args:\n");
PRINTK ("%0x%0x%0x%0x\n", a,b,c,d);
}
Main.c
//--------------------------------------------------------------------------------
int main ()
{
Test_asm_args ();
for (;;);
}
The program starts with the main function, main calls the Test_asm_args,test_asm_args call Test_c_args, and finally returns main from Test_asm_args. The code uses assembly and C to define two functions, Test_asm_args and
Test_c_args,test_asm_args calls Test_c_args, whose arguments are passed by writing the parameter values to R0~R3, and then using the BL statement
Calls to the Test_c_args. Notable in this is the red-flagged statement that Test_asm_args must precede the call to Test_c_args the current
LR into the stack, call the end of the Test_c_args and then save the LR just saved in the stack back to the PC, so as to return to the main function.
If the Test_c_args parameter is 8. This situation Test_asm_args how the parameters should be passed.
Example 2:
Test_asm_args.asm
//--------------------------------------------------------------------------------
IMPORT Test_c_args; Declare Test_c_args function
Area test_asm, CODE, READONLY
EXPORT Test_asm_args
Test_asm_args
STR LR, [sp, #-4]!; Save current LR
LDR r0,=0x1; parameter 1
LDR r1,=0x2; parameter 2
LDR r2,=0x3; parameter 3
LDR r3,=0x4; parameter 4
LDR r4,=0x8
STR r4,[sp,#-4]!; parameter 8 into stack
LDR r4,=0x7
STR r4,[sp,#-4]!; parameter 7 into stack
LDR r4,=0x6
STR r4,[sp,#-4]!; parameter 6 into stack
LDR r4,=0x5
STR r4,[sp,#-4]!; parameter 5 into stack
BL Test_c_args_lots
ADD sp, SP, #4; Clear the stack of parameter 5, the SP points to parameter 6 after this statement is done
ADD sp, SP, #4; Clear the stack of parameter 6, the SP points to parameter 7 after this statement is done
ADD sp, SP, #4; Clear the stack of parameter 7, the SP points to parameter 8 after this statement is done
ADD sp, SP, #4; Clear the stack of parameter 8, after this statement the SP points to LR
LDR pc, [sp], #4; load LR into PC (return main function)
End
Test_c_args.c
//--------------------------------------------------------------------------------
void Test_c_args (int a,int b,int c,int d,int e,int f,int g,int h)
{
PRINTK ("test_c_args_lots:\n");
PRINTK ("%0x%0x%0x%0x%0x%0x%0x%0x\n")
A,B,C,D,E,F,G,H);
}
Main.c
//--------------------------------------------------------------------------------
int main ()
{
Test_asm_args ();
for (;;);
}
This part of the code and instance 1 of the code is mostly the same, the difference is the number of Test_c_args parameters and the Test_asm_args of the parameter transfer.
In Test_asm_args, parameter 1~ parameter 4 is passed by R0~R3, and parameter 5~ parameter 8 is passed by pressing it into the stack, but note that the sequence of the four stack parameters is in the order of parameter 8-> parameter 7-> parameters 6-> The order of parameter 5 into the stack.
The stack contents are as follows until the Test_c_args is called:
sp->+----------+
| Parameter 5 |
+----------+
| Parameter 6 |
+----------+
| Parameter 7 |
+----------+
| Parameter 8 |
+----------+
| LR |
+----------+
Test_c_args execution returns, the SP is set, the parameters of the previous stack are cleared, and the LR is loaded into the PC to return the main function, before the LDR pc, [sp], #4 instructions stack contents are as follows:
+----------+
| Parameter 5 |
+----------+
| Parameter 6 |
+----------+
| Parameter 7 |
+----------+
| Parameter 8 |
sp->+----------+
| LR |

+----------+

C in Embedded assembly language
Here is an example to illustrate how to
Embedded assembly in C language
C
Language files
*.c
#include <stdio.h>
void my_strcpy (const char *SRC, char *dest) {
Char ch;
__asm{
Loop
LDRB ch, [src], #1//Here C language uses pointers for parameter passing, the advantage of which is the address in the pointer, which can be manipulated using indirection
STRB ch, [dest], #1//src and dest are pointer parameters of the C function, which is equivalent to reading data using the contents of the secondary cell as the address
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 example, the value transfer between the C language and the assembly is achieved by the pointer to the C language, because the
Addresses should be addressed, so access is also available in the Assembly.


Using C-defined global variables in the assembly

Inline assembler does not need to edit assembly language files separately, but there are many limitations. When the compilation of code is more often placed in a separate assembly document, it is necessary to compile documents and
The easiest way to make some data transfer between C files is to use global variables. The following is an example of a C language and assembly language sharing global variables:
C
Language files
*.c
#include <stdio.h>
int gvar=12;
extern asmdouble (void);
int main () {
printf ("Original value of Gvar is:%d", gvar_1);
Asmdouble ();
printf ("Modified value of Gvar is:%d", gvar_1);
return 0;
}

assembly language Files
*. S
Area Asmfile, CODE, READONLY EXPORT asmdouble
IMPORT Gvar
Asmdouble
Ldr R0, =gvar
LDR R1, [R0]
mov R2, #2
Mul R3, R1, R2
STR R3, [R0]
mov pc, LR
End

In this example, the assembly file and the C file pass the global variable Gvar and function asmdouble, note that the declaration of the keyword extern and import

atpcs function Call rule:

atpcs Specify the basic rules for calling between subroutines, the usage rules of the registers, the rules for using the stack, and the rules for passing parameters. 1 Registers use the rule subroutine to pass the parameter between the registers R0~R3, when the number of parameters is more than 4, use the stack to pass the parameter.
At this time R0~R3 can be recorded as A1~A4. In the subroutine, use the register R4~r11 to save the local variables. So be aware of saving and restoring these registers when making subroutine calls.
At this time R4~r11 can be recorded as V1~V8.
The register R12 is used to save the stack pointer SP and use the register out of the stack when the subroutine returns, as an IP. The register R13 is used as the stack pointer and is recorded as an SP. The register R14 is called the link Register, is credited as LR.
The register is used to hold the return address of the subroutine.
Register R15 is called a program counter and is recorded as a PC.
2 The use rule of the stack atpcs the stack with the full decrement type (fd,full descending), that is, the stack grows downward by reducing the memory address, and the stack pointer points to the lowest address that contains the valid data item.
3 The first 4 of the parameter's pass rule integer parameters are passed by using R0~R3, while the other parameters use stack pass, and the floating-point parameters are passed by a series of sequential FP registers that have the lowest number and are able to meet the needs. Returns a 32-bit integer when the subroutine returns, returns through R0, and returns the result to a 64-bit integer, through r0 and R1, and so on. When the result is a floating-point number, it is returned through the registers of the floating-point operator F0, D0, or S0. 
2, the Assembler program calls the method of C program assembler writing to follow the ATPCS rules to ensure that the program calls when the parameters are correctly passed.
The method of calling C program in Assembler is to first declare the C language function to be invoked in advance by using the import pseudo instruction in the assembler, and then invoke the C function through the BL instruction.
For example, in a C source file, the following summation function is defined: int add (int x,int y) {return (x+y);} The assembler structure that calls the Add () function is as follows: IMPORT add; Declare the C function to invoke ...
MOV r0,1 mov r1,2 BL add; call C function Add ... When a function call is made, the r0 and R1 are used to implement parameter passing, and the return result is brought back by R0.
After the function call ends, the R0 value becomes 3. 3, the C program calls the Assembler procedure C program calls the assembler, the assembler's writing also must follow the atpcs rule, in order to ensure that the program calls when the parameters are passed correctly.
The Assembly subroutine is invoked in the C program by declaring the invoked subroutine in the assembler, indicating that the subroutine will be called in another file, and then using the extern keyword in the C program to declare the Assembly subroutine to invoke as an external function.
For example, the following summation function is defined in an assembly source file: EXPORT Add, declaration add subroutine will be called by external function ... add, Sum subroutine add add R0,r0,r1 MOV pc,lr ... The add assembler subroutine is invoked in the main () function of a C program: extern int Add (int x,int y); Declaration Add is an external function void main () {int a=1,b=2,c; C=add (a,b);//Call Add subroutine ...} when the main () function calls the add assembler, the value of variable A and B is given to r0 and R1, and the return result is brought back by R0. and assign the value to the variable C.
After the function call ends, the value of variable C becomes 3. 4, c program embedded assembly statements in C language Embedded assembly statements can achieve some high-level language can not be implemented or not easy to implement functions. Time-pressing functions can also be implemented by inline assembly statements in C language.
The embedded assembler supports most of the arm and thumb directives, but does not support the underlying functionality such as directly modifying a PC's jump, nor does it directly refer to variables in C language.
Embedded assembly statements in the form of independent definition of the function body, its syntax format is: __asm {instruction [; instruction] ...
[directive]} where "__asm" is the key word for inline assembly statements, it is important to note that there are two underscores in front. Between directivesSeparated by semicolons, if an instruction occupies more than one line, use the hyphen "\" In addition to the last line. 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.