Introduction: In the main function of the C program, the user inputs any integers, and then calls a function written in ARM assembly in main (in which the sorting function of these integers is completed), and then outputs these sorted integers in the main function of the C program.
main.c
#include 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 scanf("%d", array+i); } sort(array, num); //Call the corresponding assembly function, pay attention to the analysis of the parameter transfer process printf("The Result is: n"); for(i = 0; i } return 0; } Here is the corresponding Sort.s: .section .text; declared as a code section .globl sort; declare global variables sort: ; A colon is required in Linux 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 stored in r0 and r1, representing the first address and number of elements of the array respectively. Use Arm cross-compilation through /-------------------------------------------------------------------------------------------------------------------------------------- For ARM system, the mixed calls between functions written in different languages follow ATPCS (ARM-Thumb Procedure Call Standard). ATPCS mainly defines the rules for passing parameters when calling functions and how to return from functions. For details about ATPCS, please refer to Section 2.1 of ADS1.2 Online Books - Developer Guide. This document will talk about how to pass parameters when calling C functions in assembly code and how to return correctly from C functions. Different from the parameter passing rules of x86, ATPCS recommends that the number of formal parameters of a function should not exceed 4. If the number of formal parameters is less than or equal to 4, the formal parameters are passed through the four registers R0, R1, R2, and R3; if the number of formal parameters is greater than 4, the part greater than 4 must be passed through the stack. Let's first discuss the case where the number of formal parameters is 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 to 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 %0xn",a,b,c,d); } main.c //-------------------------------------------------------------------------------- int main() { test_asm_args(); for(;;); } The program starts from the main function. Main calls test_asm_args, test_asm_args calls test_c_args, and finally returns to 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. The parameter passing method is to write parameter values to R0~R3 respectively, and then use bl statement to call test_c_args. The statement marked in red is worth noting. Before calling test_c_args, test_asm_args must push the current lr into the stack. After calling test_c_args, write the lr just saved in the stack back to pc, so that it can return to the main function. What if test_c_args has 8 parameters? In this case, how should test_asm_args pass the parameters? 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 is pushed onto the stack ldr r4,=0x7 str r4,[sp,#-4]! ; Parameter 7 is pushed onto the stack ldr r4,=0x6 str r4,[sp,#-4]! ; Parameter 6 is pushed onto the stack ldr r4,=0x5 str r4,[sp,#-4]! ; Parameter 5 is pushed onto 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 the 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 to 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 %0xn", a,b,c,d,e,f,g,h); } main.c //-------------------------------------------------------------------------------- int main() { test_asm_args(); for(;;); } This part of the code is mostly the same as the code in Example 1. The only difference is the number of parameters of test_c_args and the parameter passing method of test_asm_args. In test_asm_args, parameters 1 to 4 are still passed through R0~R3, while parameters 5 to 8 are passed by pushing them into the stack. However, it should be noted that the order in which these four parameters are pushed into the stack is parameter 8-> parameter 7-> parameter 6-> parameter 5. Until test_c_args is called, the stack contents are as follows: sp->+----------+ | Parameter 5 | +----------+ | Parameter 6 | +----------+ | Parameter 7 | +----------+ | Parameter 8 | +----------+ | lr | +----------+ After test_c_args returns, sp is set to clear the previously pushed parameters, and finally lr is loaded into pc to return to the main function. Before executing the LDR pc, [sp], #4 instruction, the stack content is as follows: +----------+ | Parameter 5 | +----------+ | Parameter 6 | +----------+ | Parameter 7 | +----------+ | Parameter 8 | sp->+----------+ | lr | +----------+
Previous article:Analysis and solutions of three interrupt return situations of ARM microcontroller
Next article:ARM processor exception handling steps
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Application of servo motor in automatic control
- MSP430G2452 implements heart rate monitoring based on ECG
- 【BLE 5.3 wireless MCU CH582】10. BLE broadcaster role
- Complete Flash Recording in CCS v5
- The problem of open circuit at the input end of the same-phase amplifier circuit and output oscillation
- Dear hardware engineers, can you solve differential equations?
- Temperature Problem Solved for You (V) Efficient Cold Chain Management through Scalable Temperature Sensors
- ARM CORTEX-M3 core architecture understanding summary
- Introduction to TI's three-phase Vienna PFC solution
- FPGA PLL Loss of Lock