ARM calling convention

Publisher:诚信与爱Latest update time:2020-01-06 Source: eefocusKeywords:ARM  calling  convention Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

int bar( int a, int b, int c, int d, int e, int f, int g )

{

  int array2[ 7 ];

  array2[ 0 ] = a + b;

  array2[ 1 ] = b + c;

  array2[ 2 ] = c + d;

  array2[ 3 ] = d + e;

  array2[ 4 ] = e + f;

  array2[ 5 ] = f + g;

  array2[ 6 ] = g + a;

  return array2[ 0 ] + array2[ 1 ] + array2[ 2 ] + array2[ 3 ] + array2[ 4 ]

    + array2[ 5 ] + array2[ 6 ];

}


int foo( int a, int b, int c, int d, int e, int f, int g )

{

  int array1[ 7 ];

  array1[ 0 ] = a + b;

  array1[ 1 ] = b + c;

  array1[ 2 ] = c + d;

  array1[ 3 ] = d + e;

  array1[ 4 ] = e + f;

  array1[ 5 ] = f + g;

  array1[ 6 ] = g + a;


  

  return bar( array1[ 0 ], array1[ 1 ], array1[ 2 ], array1[ 3 ], array1[ 4 ],

    array1[ 5 ], array1[ 6 ] );

}


int func( int * buffer )

{

  int a, b, c, d, e, f, g, h;

  a = 1 + buffer[ 0 ];

  b = 2 + buffer[ 1 ];

  c = 3 + buffer[ 2 ];

  d = 4 + buffer[ 3 ];

  e = 5 + buffer[ 4 ];

  f = 6 + buffer[ 5 ];

  g = 7 + buffer[ 6 ];

  h = foo( a, b, c, d, e, f, g );


  return h;

}


int main( )

{

  int array0[ 7 ];

  array0[ 0 ] = 0;

  array0[ 1 ] = 1;

  array0[ 2 ] = 2;

  array0[ 3 ] = 3;

  array0[ 4 ] = 4;

  array0[ 5 ] = 5;

  array0[ 6 ] = 6;

  while ( func( array0 ) )


  {

  }

}

int main( )

{

main:

    0x8070252: 0xb500         PUSH      {LR}

    0x8070254: 0xb087         SUB       SP, SP, #0x1c

  array0[0] = 0;

    0x8070256: 0x2000         MOVS      R0, #0

    0x8070258: 0x9000         STR       R0, [SP]

  array0[1] = 1;


    0x807025a: 0x2001         MOVS      R0, #1

    0x807025c: 0x9001         STR       R0, [SP, #0x4]

  array0[2] = 2;

    0x807025e: 0x2002         MOVS      R0, #2

    0x8070260: 0x9002         STR       R0, [SP, #0x8]

  array0[3] = 3;

    0x8070262: 0x2003         MOVS      R0, #3

    0x8070264: 0x9003         STR       R0, [SP, #0xc]

  array0[4] = 4;

    0x8070266: 0x2004         MOVS      R0, #4

    0x8070268: 0x9004         STR       R0, [SP, #0x10]

  array0[5] = 5;

    0x807026a: 0x2005         MOVS      R0, #5

    0x807026c: 0x9005         STR       R0, [SP, #0x14]

  array0[6] = 6;

    0x807026e: 0x2006         MOVS      R0, #6

    0x8070270: 0x9006         STR       R0, [SP, #0x18]

  while ( func(array0) )

??main_0:

    0x8070272: 0xa800         ADD       R0, SP, #0x0

    0x8070274: 0xf7ff 0xffc3  BL        func                    ; 0x80701fe

    0x8070278: 0x2800         CMP       R0, #0

    0x807027a: 0xd1fa         BNE.N     ??main_0                ; 0x8070272

}

int main( )

{

main:

    0x8070252: 0xb500         PUSH      {LR}

    0x8070254: 0xb087         SUB       SP, SP, #0x1c

 


Before executing PUSH {LR}, SP = 0x20000400, after executing PUSH {LR}, LR is pushed onto the stack, SP = 0x200003FC


Then execute SUB SP, SP, #0x1c, allocate 28 bytes for local variables, SP = 0x200003E0


    0x8070272: 0xa800 ADD R0, SP, #0x0

    0x8070274: 0xf7ff 0xffc3 BL func ; 0x80701fe

Calling func()



int func(int * buffer)

{

func:

    0x80701fe: 0xe92d 0x4ff0  PUSH.W    {R4-R11, LR}

    0x8070202: 0xb085         SUB       SP, SP, #0x14

    0x8070204: 0x0004         MOVS      R4, R0

    ... ... ... ...

  h = foo(a, b, c, d, e, f, g);

PUSH .W {R4-R11, LR}, SUB SP, SP, #0x14, save registers, allocate space for local variable a, other variables b,c,d,e,f,g use registers R5-R10

h Use register R11

Allocate space for three variables at the same time, use them to pass parameters through the stack, and call foo(a, b, c, d, e, f, g)

  h = foo(a, b, c, d, e, f, g);

    0x8070230: 0xf8cd 0xa008  STR.W     R10, [SP, #0x8]     g

    0x8070234: 0xf8cd 0x9004  STR.W     R9, [SP, #0x4]      f

    0x8070238: 0xf8cd 0x8000  STR.W     R8, [SP]            e

    0x807023c: 0x003b         MOVS      R3, R7              d

    0x807023e: 0x0032         MOVS      R2, R6              c    

    0x8070240: 0x0029         MOVS      R1, R5              b

    0x8070242: 0x9803         LDR       R0, [SP, #0xc]      a 

    0x8070244: 0xf7ff 0xffad  BL        foo                     ; 0x80701a2

    0x8070248: 0x4683         MOV       R11, R0

  return h;

    0x807024a: 0x4658         MOV       R0, R11

    0x807024c: 0xb005         ADD       SP, SP, #0x14

    0x807024e: 0xe8bd 0x8ff0  POP.W     {R4-R11, PC}


foo(a, b, c, d, e, f, g) : a -> R0, b -> R1, c -> R2, d -> R3, e -> [SP, #0x00], f -> [SP, #0x04], e -> [SP, #0x08]

 

foo:

    0x80701a2: 0xe92d 0x47f0  PUSH.W    {R4-R10, LR}

    0x80701a6: 0xb08a         SUB       SP, SP, #0x28

    0x80701a8: 0x0004 MOVS R4, R0 a pass through register 

    0x80701aa: 0x000d MOVS R5, R1 b pass through register

    0x80701ac: 0x0016 MOVS R6, R2 c pass through register

    0x80701ae: 0x001f MOVS R7, R3 d pass through register 

    0x80701b0: 0xf8dd 0x8048 LDR.W R8, [SP, #0x48] e passed through the stack

    0x80701b4: 0xf8dd 0x904c LDR.W R9, [SP, #0x4c] f passed through the stack

    0x80701b8: 0xf8dd 0xa050 LDR.W R10, [SP, #0x50] g passed through the stack


PUSH .W {R4-R10, LR}, SUB SP, SP, #0x28, save registers, allocate space for local variables array1[7], and allocate space for 3 variables for passing parameters through the stack, call

bar( array1[ 0 ], array1[ 1 ], array1[ 2 ], array1[ 3 ], array1[ 4 ], array1[ 5 ], array1[ 6 ] );

foo (a, b, c, d, e, f, g ) : a, b, c, d are passed via registers, e, f, g are passed via the stack

Get the parameters, calculate them, store them in the local variable array1[7], and then prepare to call bar()

array1[ 0 ], array1[ 1 ], array1[ 2 ], array1[ 3 ] are passed via registers

array1[ 4 ], array1[ 5 ], array1[ 6 ] are passed via the stack

  return bar( array1[0], array1[1], array1[2], array1[3], array1[4], array1[5], array1[6] );

    0x80701e0: 0x9809         LDR       R0, [SP, #0x24]          array1[6]

    0x80701e2: 0x9002         STR       R0, [SP, #0x8]            


    0x80701e4: 0x9808         LDR       R0, [SP, #0x20]      array1[5]      

    0x80701e6: 0x9001         STR       R0, [SP, #0x4]


    0x80701e8: 0x9807         LDR       R0, [SP, #0x1c]          array1[4]

    0x80701ea: 0x9000         STR       R0, [SP]


    0x80701ec: 0x9b06         LDR       R3, [SP, #0x18]          array1[3]

    0x80701ee: 0x9a05         LDR       R2, [SP, #0x14]          array1[2]

    0x80701f0: 0x9904         LDR       R1, [SP, #0x10]          array1[1]

    0x80701f2: 0x9803         LDR       R0, [SP, #0xc]           array1[0]


    0x80701f4: 0xf7ff 0xffa5  BL        bar                     ; 0x8070142

    0x80701f8: 0xb00a         ADD       SP, SP, #0x28

    0x80701fa: 0xe8bd 0x87f0  POP.W     {R4-R10, PC}

bar:

    0x8070142: 0xb4f0         PUSH      {R4-R7}

    0x8070144: 0xb087         SUB       SP, SP, #0x1c

    0x8070146: 0x0004         MOVS      R4, R0                 a <- array1[0] 

    0x8070148: 0x9d0b LDR R5, [SP, #0x2c] e <- array1[4] -- Parameters passed via the stack

    0x807014a: 0x9e0c LDR R6, [SP, #0x30] f <- array1[5] -- Parameters passed via the stack

    0x807014c: 0x9f0d LDR R7, [SP, #0x34] g <- array1[6] -- Parameters passed via the stack


PUSH.W {R4-R7, LR}, SUB SP, SP, #0x1C, save registers, allocate space for local variables array2[7]

Keywords:ARM  calling  convention Reference address:ARM calling convention

Previous article:ARM Memory Copy
Next article:Cortex-M3 and Cortex-M4 Memory Organization

Recommended ReadingLatest update time:2024-11-16 12:02

ARM connector error
When writing an ARM program with RVCT3.1, a connection error occurred: Error: L6915E: Library reports error: scatter-load file declares no heap or stack regions and __user_initial_stackheap is not defined. I found some information on the Internet and found that the compiler did not define Image after using the custom s
[Microcontroller]
Common causes and solutions for MCU/ARM crashes
A few days ago, when I was writing ARM, the computer often crashed for unknown reasons. Here I collected some better answers and solutions for your reference. Possible Causes: An oscillator stops oscillating It can also be divided into oscillator stopping caused by unstable power supply voltage or strong inter
[Microcontroller]
ARM Learning "Ten" - About STM32 RTC debugging
I have been debugging the RTC part of STM32 these two days. I originally planned to make a perpetual calendar, but now it seems that it cannot be realized for the time being. Why do I say this? Because RTC has very high requirements for crystal oscillators. It must be a 32768 crystal oscillator with 6p load capacitors.
[Microcontroller]
Parallel optimization of serial quick sort algorithm using embedded ARM multi-core processor
At present, embedded multi-core processors have been widely used in the field of embedded devices, but embedded system software development technology is still stuck in the traditional single-core mode, and has not fully utilized the performance of multi-core processors. Program parallel optimization is currently used
[Microcontroller]
Parallel optimization of serial quick sort algorithm using embedded ARM multi-core processor
CMake sets up arm-linux-gcc cross compiler
Host: Ubuntu 10.04 Cross compiler: EABI-4.3.3 CMake uses the system's gcc and g++ compilers by default in Ubuntu. To compile programs under arm, arm-linux-gcc must be used. CMake needs to be set up (by specifying the cross compiler in CMakeLists.txt). Add relevant settings at the beginning of CMakeLists.txt: #In
[Microcontroller]
Clock Analysis of ARM Linux S3C2440
S3c2440 Clock & Power Management The clock consists of three parts: Clock control, USB control, and Power control The clock control part can generate the clock FCLK for the ARM core, HCLK for the AHB bus peripherals, and PLCK for the APB bus peripherals. The s3c2440 has two built-in PLLs, one for FCLK, HCLK, an
[Microcontroller]
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]
Which one should I choose? DSP vs ARM with DSP functions
  Recently, in a project in the field of industrial control, I saw that the early engineering designers designed a pairing of Cortex-M3 microprocessor and TI  DSP to complete the entire project. "Why not use the Cortex-M4 core?" This question immediately popped up. Today, I carefully checked and made a simple
[Embedded]
Which one should I choose? DSP vs ARM with DSP functions
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号