C language functions and assembler functions call each other)

Source: Internet
Author: User

In the main function of the C program, it receives any integer input by the user, and then calls the function compiled using arm assembly in the main program (this function completes sorting of these integers ), then, output these sorted integers in the main function of the C program.

Main. c

#include <stdio.h>
int main()

{
Int I = 0;
Int num = 0;
Int * array = NULL;
While (Num <= 0) // enter the number of elements in the array

    {
printf("please enter the number of elements:\n");
scanf("%d",&num);
if(num > 0)

        {
break;
}
}
if(NULL == (array = (int *)malloc(num*sizeof(int))))

{
Printf ("malloc failed! \ N ");
Exit (-1 );
}
Printf ("Please enter the elements: \ n ");
For (I = 0; I <num; I ++ ){
Printf ("\ n % d: \ t", I );
Scanf ("% d", array + I );
}
Sort (array, num); // call the corresponding Assembly function. Analyze the parameter passing process.
Printf ("the result is: \ n ");
For (I = 0; I <num; I ++ ){
Printf ("% d: \ t % d \ n", I, * (array + I ));
}
Return 0;
}

 

Below is the corresponding sort. S:

. Section. Text; declared as a code segment
. Globl sort; declare global variables
Sort:; in Linux, a colon is required.
MoV R2, #0
MoV R8, R0
MoV R9, R0
Loop1:
Sub R1, R1, #1
CMP R2, r1
Add R1, R1, #1
Beq end
MoV R6, r2
Add R3, R2, #1
Loop2:
CMP R3, r1
Beq continue1
MoV R3, R3, LSL #2
Add R8, R8, r3
LDR R5, [R8]
MoV R6, R6, LSL #2
Add R9, R9, R6
LDR R4, [R9]
CMP R4, R5
Bgt exchange
Continue2:
Sub R8, R8, r3
MoV R3, R3, LSR #2
Sub R9, R9, R6
MoV R6, R6, LSR #2
Add R3, R3, #1
B loop2
Exchange:
STR R4, [R8]
STR R5, [R9]
B continue2
Continue1:
Add R2, R2, #1
B loop1

end:

 

Note: The two variables passed through APCs are saved in R0 and R1, which respectively indicate the first address of the array and the number of elements.
Using arm cross-Compilation

 

/Certificate /--------------------------------------------------------------------------------------------------------------------------------------

For the arm system, the mix CILS between functions written in different languages follows the atpcs (ARM-thumb procedure call standard ), atpcs mainly defines the transmission rules of parameters during function calls and how to return parameters from functions. For details about atpcs, see section 2.1 of ads1.2 online books -- developer guide. This document describes how to pass parameters and return correct results from C functions when calling c Functions in assembly code.
Unlike x86 parameter passing rules, atpcs recommends that the function have no more than four parameters. If the number of parameters is less than or equal to 4, the parameter is composed of r0, R1, R2, r3 registers are passed. If the number of parameters is greater than 4, the parts greater than 4 must be passed through the stack.
We will first discuss the situation where the number of parameters is 4.

Instance 1:
Test_asm_args.asm
//--------------------------------------------------------------------------------
Import test_c_args; declare the test_c_args Function
Area test_asm, code, readonly
Export test_asm_args
Test_asm_args
Str lr, [Sp, #-4]! ; Save the 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 the c Function
Ldr pc, [Sp], #4; load LR into PC (return the 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 runs from the main function. Main calls test_asm_args, test_asm_args calls test_c_args, and 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, and the parameter passing method is to R0 ~ R3 writes the parameter values respectively, and then uses the BL statement to call test_c_args. Note that the statement marked in red is used. Before test_asm_args calls test_c_args, the current LR must be put into the stack. After test_c_args is called, The LR saved in the stack is written back to the PC, in this way, it can be returned to the main function.
What if test_c_args has eight parameters? In this case, how should we PASS Parameters in test_asm_args?
Instance 2:
Test_asm_args.asm
//--------------------------------------------------------------------------------
Import test_c_args; declare the test_c_args Function
Area test_asm, code, readonly
Export test_asm_args
Test_asm_args
Str lr, [Sp, #-4]! ; Save the 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 the stack
LDR R4, = 0x7
STR R4, [Sp, #-4]! ; Parameter 7
LDR R4, = 0x6
STR R4, [Sp, #-4]! ; Parameter 6
LDR R4, = 0x5
STR R4, [Sp, #-4]! ; Parameter 5 into the stack
BL test_c_args_lots
Add SP, SP, #4; clear parameter 5 in the stack. After this statement is executed, SP points to parameter 6.
Add SP, SP, #4; clear parameter 6 in the stack. After this statement is executed, SP points to parameter 7.
Add SP, SP, #4; clear parameter 7 in stack. After this statement is executed, SP points to parameter 8.
Add SP, SP, #4; clear parameter 8 in the stack. After this statement is executed, SP points to lR
Ldr pc, [Sp], #4; load LR into PC (return the 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 (;;);
}

Most of the Code in this part is the same as the code in instance 1. The difference is the number of parameters in test_c_args and the parameter passing method in test_asm_args.
In test_asm_args, parameter 1 ~ Parameter 4 still goes through R0 ~ R3 is passed, and the parameters are 5 ~ Parameter 8 is passed by pushing it into the stack. However, pay attention to the order of the four parameters in the stack, it is written to the stack in the order of parameter 8-> parameter 7-> parameter 6-> parameter 5.

Until test_c_args is called, The stack content is as follows:
SP-> + ---------- +
| Parameter 5 |
+ ---------- +
| Parameter 6 |
+ ---------- +
| Parameter 7 |
+ ---------- +
| Parameter 8 |
+ ---------- +
| LR |
+ ---------- +
After test_c_args returns the result, it sets sp, clears the parameters of the previous stack, loads LR into the PC, and returns the main function. After executing ldr pc, [Sp], #4 the stack content before the command is as follows:
+ ---------- +
| Parameter 5 |
+ ---------- +
| Parameter 6 |
+ ---------- +
| Parameter 7 |
+ ---------- +
| Parameter 8 |
SP-> + ---------- +
| LR |
+ ---------- +

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.