ARM C embedded asm writing

Publisher:名字太长了吗Latest update time:2020-01-03 Source: eefocusKeywords:ARM Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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.

Keywords:ARM Reference address:ARM C embedded asm writing

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

【ARM】2410 bare metal series-ADC digital-to-analog conversion
Development Environment 1. Hardware platform: FS2410 2. Host: Ubuntu 12.04 ADC Register Configuration 1. Initialize ADC (ADCCON) Set the prescaler, prescaler factor, select the A/D conversion channel, select normal mode and start the conversion 2. Determine whether the conversion is completed (ADCCON ) 3. Read con
[Microcontroller]
【ARM】2410 bare metal series-ADC digital-to-analog conversion
Simple example of arm-Linux dynamic library compilation
This article tells a simple example and explains "compiling dynamic libraries" very well.  1. Preparation  1. Use oracle VM Virtualbox software to install the Ubuntu virtual machine  2. Download the relevant software and transfer it to the virtual machine, and install the cross compiler.  2. Compile and apply  This
[Microcontroller]
Simple example of arm-Linux dynamic library compilation
Electronic system design using ARM
I. Introduction As a typical application of SOC (System On Chip), the market demand for products such as handheld phones, set-top boxes, digital cameras, GPS, personal digital assistants and Internet devices is increasing. At present, ARM-based processors have become the most widely used processors in the above-ment
[Microcontroller]
Design of matrix keyboard based on ARM and its linux driver implementation
1. Introduction ARM microprocessors have been widely used in industrial control, consumer electronics, communication systems and other fields. Matrix keyboard is a commonly used keyboard form, which designs the keys into M rows and N columns, so that a total of M+N signal lines are required, but M×N keys can be driven
[Power Management]
Design of matrix keyboard based on ARM and its linux driver implementation
Temperature measurement is widely used. This ARM-based intelligent temperature measurement system is very popular recently.
introduction       Temperature measurement and control play a vital role in today's social life. The various temperature measurement technologies currently available in the international and domestic markets cover many fields such as security inspection, market, life, fire protection, scientific research, etc. Tempera
[Microcontroller]
Temperature measurement is widely used. This ARM-based intelligent temperature measurement system is very popular recently.
Working of Embedded ARM Boot Code
(1) Define the initial entry point of the code: The initial entry point refers to the starting point when the code is running. It is unique in each image file and must be contained in each executable image file. It must also be located in the executable domain of the image file. (2) Set up the interrupt vector table
[Microcontroller]
Low-cost ARM 32-bit MCUs: Two options for developers
To use a low-cost 32-bit microcontroller, developers face two choices: processors based on the Cortex-M3 core or the ARM7TDMI core. How to make a choice? What are the selection criteria? This article mainly introduces some characteristics of the ARM Cortex-M3 core microcontroller that are different from the ARM7 to he
[Microcontroller]
Research on embedded video monitoring system based on S3C2410
1 System Hardware Structure This system adopts modular structural design concept, and divides the equipment into main control module and various functional modules. There is a unified or specific interface form between the main control module and each functional module. Users can choose different functi
[Security Electronics]
Research on embedded video monitoring system based on S3C2410
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号