ARM assembly C language C++ mutual calls

Publisher:RadiantEnergyLatest update time:2017-01-19 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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.

Reference address:ARM assembly C language C++ mutual calls

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

qt-embedded-linux-opensource-src-4.5.3 ported to s3c6410
First, you need a configured environment. The compilation environment used in this article is as follows: Host system: Ubuntu 9.10 Host compiler: gcc version 4.4.1 Cross compiler: arm-linux-gcc-4.0.1 Software resources: qt-embedded-linux-opensource-src-4.5.3.tar.gz qt-x11-opensource-src-4.5.1.tar.gz
[Microcontroller]
S3C2440 DMA driver writing and testing (32)
DMA (Direct Memory Access) That is, direct storage access. The DMA transmission method does not require the CPU to directly control the transmission. It opens a direct data transmission path for RAM and I/O devices through hardware, which can greatly improve the efficiency of the CPU. After learning so many driver
[Microcontroller]
S3C2440 DMA driver writing and testing (32)
C51 Simulator User Manual
1. Main functions and features 1. Fully simulate ports p0 and p2, user programs are simulated from address 0000. 2. Supports embedded CPU simulation such as 89C52, and can simulate standard 89C51, 89C52, 89C58 and other standard 8051 core microcontrollers, including new microcontrollers with ISP function. 3. ISP onl
[Microcontroller]
C51 Simulator User Manual
GPS and electronic compass combination, use C8051 to design a high-precision navigation and positioning system
  introduction   At present, satellite navigation has become the main direction of the development of navigation technology, self-service navigation continues to develop, and integrated navigation systems have become the main navigation method. In view of the problems that the electronic compass takes a long time to s
[Microcontroller]
GPS and electronic compass combination, use C8051 to design a high-precision navigation and positioning system
Design and implementation of network monitoring system based on AT89C52
0 Introduction Taking the intelligent system of electronic equipment fault inspection and repair skill assessment and training as an example, this paper introduces a master-slave network communication system composed of a PC and multiple single-chip microcomputers. The single-chip microcomputer control is the lo
[Microcontroller]
Design and implementation of network monitoring system based on AT89C52
PIC18f4520 microcontroller drives H1632 C language program
#include p18f4520.h #include delays.h //#pragma config OSC = HS //配置内部振荡器Fosc/4 RA7,IO口RA7 //#pragma config PWRT =OFF //#pragma config BOREN = OFF //#pragma config WDT = OFF //#pragma config MCLRE = ON //#pragma config PBADEN = OFF //#pragma config LVP = OFF #define CLK PORTCbits.RC3  #define DAT PORTCbits.RC5  #defin
[Microcontroller]
The functions, features and advantages of Tektronix MDO4024C mixed domain oscilloscope
The new MDO4000C is equipped with up to six built-in instruments, each equipped with excellent performance to meet demanding challenges. Each oscilloscope offers powerful triggering, search and analysis capabilities, and they are the only oscilloscopes on the market to offer simultaneous analog, digital and RF signal
[Test Measurement]
The functions, features and advantages of Tektronix MDO4024C mixed domain oscilloscope
Design of Fingerprint Recognition System Based on AT77C101B
1 Fingerprint Recognition Principle Capacitive sensor is a type of fingerprint recognition sensor. It captures fingerprint images through electronic measurement design. The surface is an insulating layer, and the inside is a sensor that combines about 100,000 conductive metal arrays. When the user's finger
[Medical Electronics]
Design of Fingerprint Recognition System Based on AT77C101B
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号