函数栈帧的创建与销毁(初步分析汇编语言,理解程序的底层逻辑)

函数栈帧的创建与销毁

1.寄存器

寄存器分为eax、ebx、ecx、edx、ebp、esp

其中ebp和esp这两个寄存器中存放的是地址,而其余的寄存器的作用是存储数据

esp和ebp的作用就是维护函数栈帧

esp是栈顶指针

ebp是栈底指针

每一个函数调用,都要在栈区创建一个空间

2.实例分析(汇编代码)

下面以一个程序段为例子

int Add(int x,int y)
{
    int z=0;
    z=x+y;
    return z;
}
int main()
{
    int a=0;
    int b=20;
    int c=0;
    c=Add(a,b);
    printf("%d\n",c);
    return 0;
}

VS2013中,按下F10进入调试,然后点击进入反汇编,就可以调出该程序的汇编代码

**压栈(push):**给栈顶放一个元素

**出栈(pop):**从栈顶删除一个元素

代码解析:

push ebp

mov ebp,esp

sub esp,0E4h

push ebx

push esi

push edi

lea edi,[ebp-0E4h]

mov ecx,39h

mov eax,0CCCCCCCCh

rep stos dword ptr es:[edi]

int a=10; dword ptr [ebp-8],0Ah

int b=20; dword ptr [ebp-14h],14h

int c=0; dword ptr [ebp-20h],0

Add函数的压栈与main函数的压栈同理,就是为了给Add函数申请空间, 这里就不再赘述

Add函数的执行汇编代码如下:

mov eax,dword ptr[ebp+8]

add eax,dword ptr [ebp+0Ch]

mov ptr [ebp-8],eax

1.返回return 把ebp-8的值放到eax里面,而eax是个寄存器,可以存储数据

2.然后开始pop,就是弹出,或者说是出栈

3.此时Add的空间就可以销毁了,直接将ebp的值给esp就可以把栈顶指针下移

4.pop ebp使其回到main函数里面,当我们回到main函数的时候,再把所要的值放到eax里面去

问题答疑

局部变量是如何创建的?

首先为函数分配好栈帧空间,栈帧空间里面先初始化一部分空间,然后给局部变量在栈帧里面分配一点空间

为什么局部变量的值是随机值

因为随机变量是我们放进去的,如图

如果局部变量初始化,其实就是将局部变量的随机值给覆盖掉

函数是怎么传参的?传参的顺序是怎样的?

当我们要调用函数时,在调用之前,我们就已经通过push将参数压栈进入栈帧,之后在add里,通过指针的偏移量找到之前的形参

形参和实参是什么关系?

*形参是我们在压栈的时候开辟的空间,它和实参只是值是相同的,但是空间是独立的。*改变形参不会影响实参

函数调用后是怎么返回的?

当函数调用完要返回的时候,弹出ebp,就能够找到上一个函数调用的ebp,接着指针会往下走回到栈帧空间,简单来说就是通过寄存器的方式带回

我们在压栈的时候开辟的空间,它和实参只是值是相同的,但是空间是独立的。*改变形参不会影响实参

函数调用后是怎么返回的?

当函数调用完要返回的时候,弹出ebp,就能够找到上一个函数调用的ebp,接着指针会往下走回到栈帧空间,简单来说就是通过寄存器的方式带回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值