I've been playing around with an E2 phone recently, and I want to port C/Invoke ( http://www.nongnu.org/cinvoke/ ) to the E2, which has an arm CPU and Linux system. I downloaded the source code and followed the instructions to add a gcc_arm_linux arch file, but when I was modifying it, I found that there was asm code in it. I had never done this before, and I couldn't understand it at all. So, I looked up the "ARM Instruction Set" on the Internet and found the instructions I needed. The instructions were simple, but I was confused by the way of writing asm embedded in c. I also looked up the "AT&T ASM Reference", and only then did I deal with several embedded ARM assembly macros in the code. Part of the code:
/////////////////////////////////////
// macros
/////////////////////////////////////
// the following examples are given
// for x86 in MASM syntax. Some of these
// macros might not need to be implemented
// in inline assembly, depending on the arch,
// but likely most of them will.
// this macro stores the values in the input
// registers in the ArchRegParms structure passed as 'regparms'.
// In the example below we store ecx and edx because
// they are used in the fastcall convention to pass
// parameters.
// 存储“输入寄存器”中的值到regparms中。
#define ARCH_SAVE_REGPARMS(regparms)
__asm__("str %%r0, %0;
str %%r1, %1;
str %%r2, %2;
str %%r3, %3;
str %%r4, %4;
str %%r5, %5;
str %%r6, %6;
str %%r7, %7;" :
"=m" ((regparms).a1),
"=m" ((regparms).a2),
"=m" ((regparms).a3),
"=m" ((regparms).a4),
"=m" ((regparms).d0),
"=m" ((regparms).d1),
"=m" ((regparms).d2),
"=m" ((regparms).d3) :: );
// this macro does two things: copies the values
// stored in regparms into the input registers,
// and calls the function pointed to by the pointer
// ep.
// 复制regparms中的值到“输入寄存器”中,并调用指针ep指向的函数。
#define ARCH_CALL(regparms, ep)
__asm__("ldr %%r0, %0;
ldr %%r1, %1;
ldr %%r2, %2;
ldr %%r3, %3;
ldr %%r4, %4;
ldr %%r5, %5;
ldr %%r6, %6;
ldr %%r7, %7;
ldr %%r8, %8;
bx %%r8;" ::
"m" ((regparms).a1),
"m" ((regparms).a2),
"m" ((regparms).a3),
"m" ((regparms).a4),
"m" ((regparms).d0),
"m" ((regparms).d1),
"m" ((regparms).d2),
"m" ((regparms).d3),
"m" (ep) :
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7", #define ARCH_SAVE_RETURN(archvalue, type) // Saves any possible return value in archvalue.// structure given by archvalue.// saves any possible return values in the ArchRetValue
"r8");
__asm__("str %%r0, %0;
str %%r1, %1;
str %%r4, %2;" :
"=m" ((archvalue).a1),
"=m" ((archvalue).a2),
"=m" ((archvalue).d0) :: );
// stores the return values in the ArchRetValue structure
// into any place where a caller might expect to find them
// 存储archvalue中的值到“调用者”能找到的地方(寄存器)。
#define ARCH_SET_RETURN(archvalue, type)
__asm__("ldr %%r0, %0;
ldr %%r1, %1;
ldr %%r4, %2;" ::
"m" ((archvalue).a1),
"m" ((archvalue).a2),
"m" ((archvalue).d0) :
"r0",
"r1",
"r4");
// increases the stack size by bcount bytes
#define ARCH_PUT_STACK_BYTES(bcount)
__asm__("ldr %%r8, %0;
sub %%sp, %%sp, %%r8;" ::
"m" (bcount) :
"r8",
"sp");
// decreases the stack size by bcount bytes
#define ARCH_REMOVE_STACK_BYTES(bcount)
__asm__("ldr %%r8, %0;
add %%sp, %%sp, %%r8;" ::
"m" (bcount) :
"r8",
"sp");
// copies the current stack pointer into the pointer variable
// stackp
#define ARCH_GET_STACK(stackp)
__asm__("str %%r13, %0;" : "=m" (stackp) :: );
// copies the current frame pointer into the pointer variable
// framep
#define ARCH_GET_FRAME_PTR(framep)
__asm__("str %%r11, %0;" : "=m" (framep) :: );
Let's mainly talk about the embedded writing method of AT&T ASM. The format is as follows:
__asm__("instruction": "operation constraint" (output parameter): (input parameter): register constraint);
Instruction: Of course, it is the ARM assembly instruction, but it should be noted that the register must be constrained with %% to prevent conflict with parameter %.
Operation Constraint: I personally understand it as a parameter passing method, such as "=m", where "=" indicates output, and can be omitted to indicate input, "+" indicates both input and output, and "m" indicates the use of memory. In x86, it can also be "a", "b", "c", etc., indicating what kind of register to use.
Output parameter: corresponds to the variable in C code, and is the value taken from the register or memory by the assembly code for use in C code. When there are multiple parameters, separate them with commas.
Input parameters: Parameters that C code inputs to assembly code.
Register Constraint: I think it is for the compiler to check your code and prevent you from modifying the contents of registers that should not be modified.
In ARM, registers are different from those on X86. There is no ax, bx, etc. It is r0~r15, which also includes several special-purpose registers, such as: r11=fp (frame pointer), r13=sp (stack pointer), etc.
Previous article:ARM storage format big endian little endian
Next article:lpc177x_8x, 1pc32xx series chip external SDRAM configuration
Recommended ReadingLatest update time:2024-11-17 00:54
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
- BQ76930: Design help needed for BQ76930 based BMS
- Op amp circuit knowledge: voltage feedback, common indicators, good and bad judgment...
- Live broadcast at 10 am today [How to choose a suitable automotive MOSFET]
- New topic is coming! The perfect combination of simulation and theory --- opening chapter
- Butterworth filter circuit model analysis
- [Important] Core Route FPGA Learning Motherboard Schematic Diagram PCB Engineering File Open Source Sharing
- Application of the concepts of virtual short and virtual disconnect in operational amplifiers in actual product circuits
- What is the application of PWM
- Detailed explanation of protection circuit design for intelligent motor system
- Guess the questions in the electronic competition and win prizes!