Chinaunix首页 | 论坛 | 博客
  • 博客访问: 750159
  • 博文数量: 215
  • 博客积分: 291
  • 博客等级: 二等列兵
  • 技术积分: 1031
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-12 18:17
文章分类

全部博文(215)

文章存档

2016年(16)

2015年(16)

2014年(123)

2013年(60)

分类: LINUX

2013-11-27 10:42:58

本文从一个实例入手来讲解函数调用过程中栈上数据的分布。

示例代码:

#include

void func1(int a, int b, int c)

{

     a + b + c;

     return;

}

int main()

{

     int a=1,b=2,c=3;

     int d=10;

     printf("&a:0x%08x, &b:0x%08x, &c:0x%08x, &d:0x%08x\n", &a, &b, &c, &d);

     func1(a, b, c);

     return 0;

}


编译该程序,然后反汇编来看:

080483c4 <func1>:

80483c4: 55 push %ebp

80483c5: 89 e5 mov %esp,%ebp

80483c7: 90 nop

80483c8: 5d pop %ebp

80483c9: c3 ret


080483ca <main>:

80483ca: 55 push %ebp

80483cb: 89 e5 mov %esp,%ebp

80483cd: 83 e4 f0 and $0xfffffff0,%esp

80483d0: 83 ec 30 sub $0x30,%esp

80483d3: c7 44 24 2c 01 00 00 movl $0x1,0x2c(%esp) /* 局部变量a */

80483da: 00

80483db: c7 44 24 28 02 00 00 movl $0x2,0x28(%esp) /* 局部变量b */

80483e2: 00

80483e3: c7 44 24 24 03 00 00 movl $0x3,0x24(%esp) /* 局部变量c */

80483ea: 00

80483eb: c7 44 24 20 0a 00 00 movl $0xa,0x20(%esp) /* 局部变量d */

80483f2: 00

80483f3: b8 14 85 04 08 mov $0x8048514,%eax

80483f8: 8d 54 24 20 lea 0x20(%esp),%edx

80483fc: 89 54 24 10 mov %edx,0x10(%esp)

8048400: 8d 54 24 24 lea 0x24(%esp),%edx

8048404: 89 54 24 0c mov %edx,0xc(%esp)

8048408: 8d 54 24 28 lea 0x28(%esp),%edx

804840c: 89 54 24 08 mov %edx,0x8(%esp)

8048410: 8d 54 24 2c lea 0x2c(%esp),%edx

8048414: 89 54 24 04 mov %edx,0x4(%esp)

8048418: 89 04 24 mov %eax,(%esp)

804841b: e8 c0 fe ff ff call 80482e0

8048420: 8b 4c 24 24 mov 0x24(%esp),%ecx

8048424: 8b 54 24 28 mov 0x28(%esp),%edx

8048428: 8b 44 24 2c mov 0x2c(%esp),%eax

804842c: 89 4c 24 08 mov %ecx,0x8(%esp) /* 函数入参c */

8048430: 89 54 24 04 mov %edx,0x4(%esp) /* 函数入参b*/

8048434: 89 04 24 mov %eax,(%esp)            /* 函数入参a */

8048437: e8 88 ff ff ff call 80483c4

804843c: b8 00 00 00 00 mov $0x0,%eax

8048441: c9 leave

8048442: c3 ret


分析上述汇编可以得出如下函数的栈结构:

void func(int arg1,int arg2,int arg3)

{

      int v1, v2, v3;

int v4;


……

return;

}


       入参arg3

入参arg2

入参arg1

      返回地址

函数调用者的%ebp

        局变v1

        局变v2

        局变v3

        局变v4

        ……


结论:

  1. 局部变量是从左向右,从上往下入栈的;

  2. 函数调用,实参是从右向左入栈(处理)的。


以上的环境为gnu c compiler + x86


对于gnuc c compiler + powerpc,
    1. 局部变量是从下往上入栈的,栈是空递减。

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