码迷,mamicode.com
首页 > 其他好文 > 详细

【链接】函数栈帧

时间:2015-04-05 23:35:38      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:

      本节通过反汇编可执行文件得到的文件,研究函数栈帧的相关内容;


栈帧整体示意图如下

技术分享


示例代码

#include <stdio.h>
#include <iostream>
using namespace std;

int z = 10;

int add(int x, int y)
{
  return x+y+z;
}

int inc20(int x)
{
  int y = 10;
  return add(x, y);
}

int main(void)
{
  int a = 30;
  a = inc20(a);
  cout << a << endl;
  return 0;
}
说明几点

(1)本节只研究main和inc20、add之间的函数栈帧,对于cout,以及main函数之前和之后的启动和结束代码不作研究;


例子整体栈帧示意图如下

技术分享

反汇编代码

080486ac <_Z3addii>:
 80486ac:	55                   	push   %ebp
 80486ad:	89 e5                	mov    %esp,%ebp
 80486af:	8b 55 08             	mov    0x8(%ebp),%edx
 80486b2:	8b 45 0c             	mov    0xc(%ebp),%eax
 80486b5:	01 c2                	add    %eax,%edx
 80486b7:	a1 84 9a 04 08       	mov    0x8049a84,%eax
 80486bc:	01 d0                	add    %edx,%eax
 80486be:	5d                   	pop    %ebp
 80486bf:	c3                   	ret    

080486c0 <_Z5inc20i>:
 80486c0:	55                   	push   %ebp
 80486c1:	89 e5                	mov    %esp,%ebp
 80486c3:	83 ec 10             	sub    $0x10,%esp
 80486c6:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%ebp)
 80486cd:	ff 75 fc             	pushl  -0x4(%ebp)
 80486d0:	ff 75 08             	pushl  0x8(%ebp)
 80486d3:	e8 d4 ff ff ff       	call   80486ac <_Z3addii>
 80486d8:	83 c4 08             	add    $0x8,%esp
 80486db:	c9                   	leave  
 80486dc:	c3                   	ret    

080486dd <main>:
 80486dd:	8d 4c 24 04          	lea    0x4(%esp),%ecx
 80486e1:	83 e4 f0             	and    $0xfffffff0,%esp
 80486e4:	ff 71 fc             	pushl  -0x4(%ecx)
 80486e7:	55                   	push   %ebp
 80486e8:	89 e5                	mov    %esp,%ebp
 80486ea:	51                   	push   %ecx
 80486eb:	83 ec 14             	sub    $0x14,%esp
 80486ee:	c7 45 f4 1e 00 00 00 	movl   $0x1e,-0xc(%ebp)
 80486f5:	ff 75 f4             	pushl  -0xc(%ebp)
 80486f8:	e8 c3 ff ff ff       	call   80486c0 <_Z5inc20i>
 80486fd:	83 c4 04             	add    $0x4,%esp
 8048700:	89 45 f4             	mov    %eax,-0xc(%ebp)
 8048703:	83 ec 08             	sub    $0x8,%esp
 8048706:	ff 75 f4             	pushl  -0xc(%ebp)
 8048709:	68 c0 9a 04 08       	push   $0x8049ac0
 804870e:	e8 e9 fd ff ff       	call   80484fc <_ZNSolsEi@plt>
 8048713:	83 c4 10             	add    $0x10,%esp
 8048716:	83 ec 08             	sub    $0x8,%esp
 8048719:	68 6c 85 04 08       	push   $0x804856c
 804871e:	50                   	push   %eax
 804871f:	e8 38 fe ff ff       	call   804855c <_ZNSolsEPFRSoS_E@plt>
 8048724:	83 c4 10             	add    $0x10,%esp
 8048727:	b8 00 00 00 00       	mov    $0x0,%eax
 804872c:	8b 4d fc             	mov    -0x4(%ebp),%ecx
 804872f:	c9                   	leave  
 8048730:	8d 61 fc             	lea    -0x4(%ecx),%esp
 8048733:	c3                   	ret   
说明几点

(1)首先在_Z3addii找出z变量的地址和相关信息;

sykpour@sykpour:~/Desktop$ readelf -s test | grep 8049a84
    75: 08049a84     4 OBJECT  GLOBAL DEFAULT   23 z
(2)立即数前面的标识是$,popl为双字(单字为16字节)出栈,对于寄存器而言pop %esp也是栈中双字赋值给esp;如movl   $0xa,-0x4(%ebp)表示将立即数0xa存放到ebp+4地址处;而mov    0x8(%ebp),%edx表示将ebp+8地址处的内容存放到edx寄存器中


汇编注释

080486ac <_Z3addii>:
 80486ac:	55                   	push   %ebp
 80486ad:	89 e5                	mov    %esp,%ebp
 80486af:	8b 55 08             	mov    0x8(%ebp),%edx   #取参数x到edx
 80486b2:	8b 45 0c             	mov    0xc(%ebp),%eax   #取参数y到eax
 80486b5:	01 c2                	add    %eax,%edx        #x=x+y;
 80486b7:	a1 84 9a 04 08       	mov    0x8049a84,%eax   #取z的内容到eax
 80486bc:	01 d0                	add    %edx,%eax        #z=z+x;
 80486be:	5d                   	pop    %ebp
 80486bf:	c3                   	ret    

080486c0 <_Z5inc20i>:
 80486c0:	55                   	push   %ebp
 80486c1:	89 e5                	mov    %esp,%ebp
 80486c3:	83 ec 10             	sub    $0x10,%esp
 80486c6:	c7 45 fc 0a 00 00 00 	movl   $0xa,-0x4(%ebp)   #局部变量y的值
 80486cd:	ff 75 fc             	pushl  -0x4(%ebp)        #add的参数y
 80486d0:	ff 75 08             	pushl  0x8(%ebp)         #add的参数x,ebp是在main函数的栈中找的值
 80486d3:	e8 d4 ff ff ff       	call   80486ac <_Z3addii>
 80486d8:	83 c4 08             	add    $0x8,%esp         #调整栈指针
 80486db:	c9                   	leave  
 80486dc:	c3                   	ret    

080486dd <main>:
 80486dd:	8d 4c 24 04          	lea    0x4(%esp),%ecx
 80486e1:	83 e4 f0             	and    $0xfffffff0,%esp
 80486e4:	ff 71 fc             	pushl  -0x4(%ecx)
 80486e7:	55                   	push   %ebp                #保存栈帧寄存器
 80486e8:	89 e5                	mov    %esp,%ebp           #栈帧指针指向栈指针
 80486ea:	51                   	push   %ecx                #保护ecx寄存器的内容
 80486eb:	83 ec 14             	sub    $0x14,%esp          #调整栈指针,存放局部变量
 80486ee:	c7 45 f4 1e 00 00 00 	movl   $0x1e,-0xc(%ebp)    #局部变量a的值
 80486f5:	ff 75 f4             	pushl  -0xc(%ebp)          #inc20的参数x
 80486f8:	e8 c3 ff ff ff       	call   80486c0 <_Z5inc20i>
 80486fd:	83 c4 04             	add    $0x4,%esp           #调整栈指针
 8048700:	89 45 f4             	mov    %eax,-0xc(%ebp)     #cout打印的参数,直接从add的eax中取回的
 8048703:	83 ec 08             	sub    $0x8,%esp
 8048706:	ff 75 f4             	pushl  -0xc(%ebp)
 8048709:	68 c0 9a 04 08       	push   $0x8049ac0
 804870e:	e8 e9 fd ff ff       	call   80484fc <_ZNSolsEi@plt>

【链接】函数栈帧

标签:

原文地址:http://blog.csdn.net/skyuppour/article/details/44892047

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!