当前位置:首页 > 开发 > 编程语言 > Java > 正文

ARM 调用约定 calling convention

发表于: 2015-10-30   作者:互联网   来源:转载   浏览次数:
摘要: 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
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 ) )
{ } }

ARM 调用约定 calling convention_第1张图片

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 }

ARM 调用约定 calling convention_第2张图片ARM 调用约定 calling convention_第3张图片

int main( )
{
main:
    0x8070252: 0xb500         PUSH      {LR}
    0x8070254: 0xb087         SUB       SP, SP, #0x1c

 

执行 PUSH {LR} 之前, SP = 0x20000400, 执行 PUSH {LR} 之后, LR 入栈, SP = 0x200003FC

接着执行 SUB SP, SP, #0x1c, 为局部变量分配空间 28 bytes, SP = 0x200003E0

    0x8070272: 0xa800 ADD R0, SP, #0x0
    0x8070274: 0xf7ff 0xffc3 BL func ; 0x80701fe

调用 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, 保存寄存器, 为局部变量分配空间 a, 其他变量b,c,d,e,f,g 使用寄存器R5-R10

使用寄存器 R11 <图中没有显示>

同时分配3个变量的空间, 用于通过堆栈传递参数, 调用 foo(a, b, c, d, e, f, g)

ARM 调用约定 calling convention_第4张图片

  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]

 ARM 调用约定 calling convention_第5张图片

 

foo:
    0x80701a2: 0xe92d 0x47f0  PUSH.W    {R4-R10, LR}
    0x80701a6: 0xb08a         SUB       SP, SP, #0x28
    0x80701a8: 0x0004         MOVS      R4, R0                a 通过寄存器传递 
    0x80701aa: 0x000d         MOVS      R5, R1                b 通过寄存器传递
    0x80701ac: 0x0016         MOVS      R6, R2                c 通过寄存器传递
    0x80701ae: 0x001f         MOVS      R7, R3                d 通过寄存器传递 
    0x80701b0: 0xf8dd 0x8048  LDR.W     R8, [SP, #0x48]       e 通过堆栈传递
    0x80701b4: 0xf8dd 0x904c  LDR.W     R9, [SP, #0x4c]       f 通过堆栈传递
    0x80701b8: 0xf8dd 0xa050  LDR.W     R10, [SP, #0x50]      g 通过堆栈传递

PUSH .W {R4-R10, LR}, SUB SP, SP, #0x28, 保存寄存器, 为局部变量分配空间 array1[7], 同时分配3个变量的空间, 用于通过堆栈传递参数, 调用

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 通过寄存器传递, e, f, g 通过堆栈传递

获取参数, 运算之后, 存入局部变量 array1[7], 然后准备调用 bar()

array1[ 0 ], array1[ 1 ], array1[ 2 ], array1[ 3 ]  通过寄存器传递

array1[ 4 ], array1[ 5 ], array1[ 6 ] 通过堆栈传递

  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]            
0
x80701e4: 0x9808 LDR R0, [SP, #0x20]      array1[5]       0x80701e6: 0x9001 STR R0, [SP, #0x4]
0
x80701e8: 0x9807 LDR R0, [SP, #0x1c] array1[4] 0x80701ea: 0x9000 STR R0, [SP]
0
x80701ec: 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]
0
x80701f4: 0xf7ff 0xffa5 BL bar ; 0x8070142 0x80701f8: 0xb00a ADD SP, SP, #0x28 0x80701fa: 0xe8bd 0x87f0 POP.W {R4-R10, PC}

 

ARM 调用约定 calling convention_第6张图片

 

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] -- 通过堆栈传递的参数
    0x807014a: 0x9e0c         LDR       R6, [SP, #0x30]        f <- array1[5] -- 通过堆栈传递的参数
0x807014c: 0x9f0d LDR R7, [SP, #0x34] g <- array1[6] -- 通过堆栈传递的参数

 

PUSH.W {R4-R7, LR}, SUB SP, SP, #0x1C, 保存寄存器, 为局部变量分配空间 array2[7]

ARM 调用约定 calling convention_第7张图片

 

ARM 调用约定 calling convention

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
http://zh.wikipedia.org/wiki/X86%E8%B0%83%E7%94%A8%E7%BA%A6%E5%AE%9A 这里描述了在x86芯片架构
【x86_64 Assembler Calling Convention】  1、x86_64 registers      (r8-r15 follow the sam
很久没更新blog了, 最近比较忙. 这篇文章转自我的onenote, 所以中英文都有, 记给自己, 也分享给大家
函数调用约定和堆栈 1 什么是堆栈 编译器一般使用堆栈实现函数调用。堆栈是存储器的一个区域,嵌入
Convention插件的主要特点是“约定优于配置”。 Action的搜索和映射约定 为了能够使用Convention插件
最近在写一些字符串函数的优化,用到x64汇编,我也是第一次接触,故跟大家分享一下。 x86:又名 x32
因为需要在QNX Momentics中混合C语言和ARM汇编进行开发,于是初步了解了一下APCS。和大家分享一下我
Convention Plugin 从struts2.1版本开始,Convention Plugin作为替换替换Codebehind Plugin来实现St
在Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号