函数调用帧的格式

16 篇文章 1 订阅


       最近好像对关于函数调用过程中,产生的函数帧在stack中的格式很敢兴趣,在今天研究了一下午的汇编代码以后我觉得应该有点小小的了解了。

      首先贴一段简单的代码,用来产生汇编代码,然后再开始分析这个桟帧的分析。

       

#include <stdio.h>

int global_val = 3;
void display(int a, int b)
{
    int i = 0;
    int j = 0;
    a = b;
}

void int_max(int a, int b)
{
    int max_ = 0;
    

    display(a,b);

    printf("hello.world!\n");
}

这个代码是没有什么意思的,不过只是为了让我能看见调用的过程。

int_max:
	1.pushl	%ebp
	2.movl	%esp, %ebp
	3.subl	$40, %esp
	4.movl	$0, -12(%ebp)
	5.movl	12(%ebp), %eax
	6.movl	%eax, 4(%esp)
	7.movl	8(%ebp), %eax
	8.movl	%eax, (%esp)
	9.call	display
	10.movl	$.LC0, (%esp)
	11.call	puts

这段是int_max函数的汇编程序,那我对这个汇编进行了小小的分析,就我现在所知道的是,在函数调用的过程中

1.先将函数的参数进行压stack

2.保存现场的一些东西(寄存器的值),将返回地址压入stack中。

3.保存调用该函数的ebp

4.函数的局部变量之类的


在分析之前,我先要说明两个寄存器的作用:

1.esp  这个寄存器是桟顶指针吧,我是这样叫的。这个指针是指向当前函数记录的最顶端的位置。而且不论在什么时候都是值指在最上面的。

2.ebp  这个寄存器存放的是帧底指针,也就是说是指向的是当前函数的帧的最下方的位置,而不是指向stack的底部。(其实我对这个是保持一种怀疑态度,到最后的时候我在分析为什么我怀疑这个问题)

这两个指针必须要搞清楚的。不然在解析过程中很难理解这个问题。

  

          现在开始分析汇编代码,

	1.pushl	%ebp
	2.movl	%esp, %ebp
1.这两行代码在任何一个函数中都有的,意思是先将前面一个函数帧的帧底压入stack,然后将当前的桟顶指针赋值给ebp,也就是现在两个指针都指向桟顶。

        3.subl	$40, %esp
	4.movl	$0, -12(%ebp)
	5.movl	12(%ebp), %eax
	6.movl	%eax, 4(%esp)
	7.movl	8(%ebp), %eax
	8.movl	%eax, (%esp)
        

2.说明一下,stack的底部是高地址,所以stack向下进行伸展的。所以减才是压桟的过程。esp 减去0x40,0x40也就是表示保留了64BYTE的空间,可能你会奇怪明明只有一个局部变量,为什么要那么大的空间。其实不然因为在进行函数调用的时候不但要将返回地址放入stack中,而且还要将一些寄存器的值放入桟中,以便后面进行恢复。不过在代码中没有表示出来。而且关于这个的具体位置和大小也不怎么清楚。

4号代码,将0放到(epb - 12)的位置,而5号的代码是将(将参数b)放到eax中,6号是将b存入esp+4这个地方,而7,8号就是将a放到esp的位置。其实这一部可以看成为下了函数的参数进行压桟。

如果从整体来看是这样的一个过程,在调用函数的时,编译器会先将函数的参数进行压桟,而且这个压桟的过程是一个倒序的过程(不过好像这是和特定的编译有关系的),然后调用下面的指令

9.call	display
这条指针是用来调用函数的指令,call这个指令好像不是想象中的那么简单,他要做的事情挺多的,好像是保存寄存器,将返回地址进行压桟等,后面的过程就是我们分析的那样了。



哈不过还是有些问题没有解决,比如ebp这个指针的指向位置很不能理解,他被定位在返回地址上面,我觉得他应该从参数那个开始就是一帧了,还有就是返回地址在ebp前面,可是寄存器的值在ebp后面,这个也是问题,不知道能怎么样????







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值