1. Assembler accesses C language global variables
Global variables can only be called indirectly through addresses. In order to access global variables in C language, you must first introduce the global variable through the extern pseudo-instruction, and then load its address into the register.
For unsigned char type, use LDRB/STRB to access;
For unsigned short type, use LDRH/STRH to access;
For unsigned int type, use LDR/STR to access;
For char type, use LDRSB/STRSB to access;
For short types, use LDRSH/STRSH to access;
example:
.text
.global asmsubroutine
.extern globvar
asmsubroutine:
LDR R1,=globvar
LDR R0,[R1]
ADD R0,R0,#2
STR R0,[R1]
MOV PC,LR
.end
2.C program calls assembler
When a C program calls an assembler, it first declares the assembler module to be called through extern. The number of formal parameters in the declaration must be consistent with the number of variables required in the assembler module, and the parameter passing must meet the ATPCS rules. Then it is called in the C program.
example:
#include
extern void *strcopy(char*d,char*s);//module declaration
int main()
{
char*srcstr="first";
char*dststr="second";
strcopy(dststr,srcstr);//Assembly module call;
}
.text
.global strcopy
Strcopy:
LDRB R2,[R1],#1
STRB R2,[R0],#1
CMP R2,#0
BNE Sstcopy
MOV PC,LR
.end
Assembler calls C program
Before calling, parameter passing must be completed according to the number of parameters required in the C language module and the ATPCS parameter rules, that is, the first four parameters are passed through R0-R3, and the following parameters are passed through the stack, and then called using B and BL instructions.
example:
int g(int a,int b,int c,int d,int e) //C language function prototype
{
return(a+b+c+d+e);
}
The assembly language is completed by finding the result of i+2i+3i+4i+5i;
.global _start
.text
_start:
.extern g ; import c program
STR LR,{SP,-#4}!;Save PC
ADD R1,R0,R0
ADD R2,R1,R0
ADD R3,R1,R2
STR R3,{SP,#-4}!
ADD R3,R1,R1
BL g ;Call C function g
ADD SP,SP,#4
LDR PC,[SP],#4
.end
return(0);
Mutual calls between C and C++ libraries
Last night a friend asked me about calling C++ libraries in C. After lunch today, I was unable to join our group’s “daily battle” due to severe neck pain, so I made a summary of the library calling relationship between C and C++.
1. Understanding of extern "C":
Many people think that "C" stands for C language, but it is not true. "C" stands for a link convention, which is more commonly used between C and C++ languages due to their close relationship. In fact, Fortran and assembly languages are also often used because they also conform to the conventions of C implementation. The
extern "C" directive describes a link convention, which does not affect the definition of the calling function. Even if this declaration is made, the function type check and parameter conversion still follow the C++ standard, not the C standard.
2. The role of extern "C":
Different languages have different linking capabilities, which also determines the differences in the link symbols after they are compiled. For example, for a function void fun(double d), C language will compile it into a symbol like _fun. The C linker can successfully link as long as it finds the function symbol. It assumes that the parameter type information is correct. C++ will compile this function into a symbol like _fun_double or _xxx_funDxxx, adding type information to the symbol. This is why C++ can implement overloading.
So, for a library compiled with a C compiler, directly linking with C++ will inevitably lead to the problem of not being able to recognize symbols. Yes, the time has come when extern "C" is needed. It is used for this purpose. The role of extern "C" is to let the compiler know to compile and link the encapsulated function in the C language.
3. Example of calling C library in C++:
1). Make a C dynamic library:
// hello.c:
#include
void hello()
{
printf("hello\n");
}
Compile and copy to the system library directory (you can also define the library directory yourself, man ldconfig):
[root@coredump test]# gcc --shared -o libhello.so hello.c
[root@coredump test]# cp libhello.so /lib/
2). Write a C++ program to call it:
// test.cpp
#include
#ifdef __cplusplus
extern "C" { // Tell the compiler that the following code should be linked in the C linkage convention mode
#endif
void hello();
#ifdef __cplusplus
}
#endif
int main()
{
hello();
return 0;
}
Compile and run:
[root@coredump test]# g++ test.cpp -o test -lhello
[root@coredump test]# ./test
hello
[root@coredump test]#
3). Conditional compilation of __cplusplus macro:
Why do we need to add this conditional compilation? Xiao Shenyang has something to say: Sister, why is this?
Because this technology may also be used in C++ files generated by C header files. This is to establish common C and C++ files, that is, to ensure that when this file is used as a C file compilation, the C++ structure can be removed. In other words, the extern "C" syntax is not allowed in the C compilation environment.
For example: rename the above test.cpp to test.c, change the header file to stdio.h, remove the conditional compilation, and then compile with gcc to see the effect. Even if the above changes are made, it can be used normally if compiled with g++. This is what I mean by "common C and C++ files" above.
4.C calls C++ library:
It doesn't seem that difficult to call C++ library, because C++ itself has the feature of forward compatibility (towards C), plus the natural extern "C" convention, everything is so natural. It seems that it is not so easy to let C call C++ library, but it is not impossible.
I have to take a break here. It's noon, so I'm going to go out and smoke a cigarette. But I also believe that if you don't know the answer, you must be looking for bricks everywhere when you see this, and you can't wait to knock my head open. I can understand, and I'm used to it. One of my senior sisters threw a brick at me when she saw me!
Let's get back to the point, we still have to use this natural extern "C".
1) Make a C++ library:
// world.cpp
#include
void world()
{
std::cout << "world" << std::endl;
}
Compile and copy to the system library directory:
[root@coredump test]# g++ --shared -o libworld.so world.cpp
[root@coredump test]# cp libworld.so /lib/
2) Make an intermediate interface library and re-encapsulate the C++ library:
// mid.cpp
#include
void world();
#ifdef __cplusplus
extern "C" { // Even though this is a C++ program, the following function must be implemented in the C style!
#endif
void m_world()
{
world();
}
#ifdef __cplusplus
}
#endif
The method m_world is the secondary encapsulation of the world method in the libworld library. Compile and copy it to the system library directory:
[root@coredump test]# g++ --shared -o libmid.so mid.cpp -lworld
[root@coredump test]# cp libmid.so /lib/
3). The C program calls the C++ library by linking the secondary interface library:
// test.c
#include
int main()
{
m_world();
return 0;
}
Compile and run:
[root@coredump test]# gcc test.c -l mid -o test
[root@coredump test]# ./test
world
[root@coredump test]
#Note: If the C++ library contains classes, you can generate temporary objects in the secondary interface function to call the corresponding function. Of course, it depends on the actual situation.
Previous article:Basic knowledge of the overall analysis of the running process of ucos on s3c2410 - c language and stack
Next article:Issues to note when converting ARM-Linux assembly to ADS assembly
Recommended ReadingLatest update time:2024-11-16 13:42
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
- (Bonus 1) GD32L233 Review - What is Cortex-M23?
- Show off the two development boards I just exchanged
- TMS320C54x DSP/BIOS algorithm and data testing
- [National Technology N32G457 Review] ML component control
- Playing with Zynq Serial 47——[ex66] Image Histogram Equalization Processing of MT9V034 Camera
- Anlu SparkRoad Development Board Review (6) Use of FIFO IP
- Features and differences of ARM, DSP and FPGA
- [GD32L233C-START Review] 14. RT-Thread kernel and finsh ported to GD32L233
- Introduction to the classification and development history of carrier aggregation
- Share the written test questions for embedded software engineers