Chinaunix首页 | 论坛 | 博客
  • 博客访问: 923924
  • 博文数量: 63
  • 博客积分: 568
  • 博客等级: 中士
  • 技术积分: 3435
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-05 11:44
文章分类
文章存档

2016年(4)

2015年(6)

2014年(3)

2013年(27)

2012年(23)

分类: 嵌入式

2015-11-15 14:40:28

最近在分析一下ARM架构linux环境中的应用态,内核态中相关的调试方法,其中一个重要的方面就是分析函数调用的调用栈。ARM架构函数调用栈遵循APCS规则,下面通过一个例子分析一下ARM调用栈的结构。

int callfunctionA(int aa, int bb, int c, int d, int e, int f)
{
    8480:    e92d4800     push    {fp, lr}
    8484:    e28db004     add    fp, sp, #4
    8488:    e24dd018     sub    sp, sp, #24
    848c:    e50b0010     str    r0, [fp, #-16]
    8490:    e50b1014     str    r1, [fp, #-20]
    8494:    e50b2018     str    r2, [fp, #-24]
    8498:    e50b301c     str    r3, [fp, #-28]
    int a = 0;
    849c:    e3a03000     mov    r3, #0
    84a0:    e50b3008     str    r3, [fp, #-8]
    int b = 0;
    84a4:    e3a03000     mov    r3, #0
    84a8:    e50b300c     str    r3, [fp, #-12]
    printf("the a is %i, the b is %i\n", a, b);
    84ac:    e59f001c     ldr    r0, [pc, #28]    ; 84d0
    84b0:    e51b1008     ldr    r1, [fp, #-8]
    84b4:    e51b200c     ldr    r2, [fp, #-12]
    84b8:    ebffff89     bl    82e4 <_init+0x20>
    callfunctionB();
    84bc:    ebffffe0     bl    8444
    return 0;
    84c0:    e3a03000     mov    r3, #0
}
    84c4:    e1a00003     mov    r0, r3
    84c8:    e24bd004     sub    sp, fp, #4
    84cc:    e8bd8800     pop    {fp, pc}
    84d0:    000085cc     .word    0x000085cc

    callfunctionA(1, 2, 3, 4, 5, 6);
    8518:    e3a03005     mov    r3, #5
    851c:    e58d3000     str    r3, [sp]
    8520:    e3a03006     mov    r3, #6
    8524:    e58d3004     str    r3, [sp, #4]
    8528:    e3a00001     mov    r0, #1
    852c:    e3a01002     mov    r1, #2
    8530:    e3a02003     mov    r2, #3
    8534:    e3a03004     mov    r3, #4
    8538:    ebffffd0     bl    8480


从汇编来看,调用栈分为三个部分,最开始部分是部分行参,就是要传递到调用函数中的参数。然后第二部分是返回地址,和上一帧栈位置的地址
第三部分是函数局部变量的地址,但是ARM是用寄存器来传递参数的,如果传递参数超过了4个,超过的采用调用栈来传递参数。

阅读(5248) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~