【C语言初阶】函数栈帧的创建和销毁-创新互联
以下都是在VS2013环境下实现的,在不同的编译器下函数的栈帧创建略有不同。
创新互联是一家专业提供利津企业网站建设,专注与成都网站建设、网站建设、H5高端网站建设、小程序制作等业务。10年已为利津众多企业、政府机构等服务。创新互联专业的建站公司优惠进行中。1.寄存器:eax、ebx、ecx、edx等等。
与函数栈帧相关的寄存器有ebp(栈底指针)、esp(栈顶指针),这两个寄存器是来维护函数栈帧的。
2.在VS2013中,main函数也是被其他函数调用的
mainCRTStartup ---> __tmainCRTStartup ---> main
3.函数栈帧创建与销毁的过程
具体过程以下边的代码为例
#includeint Add(int x,int y)
{
int z=0;
z=x+y;
return z;
}
int main()
{
int a=10;
int b=20;
int c=0;
c=Add(a,b);
printf(%d\n",c);
return 0;
}
当程序运行后转到反汇 编,通过反汇编观察程序的运行
1.push ebp 将ebp的值压栈
2.mov ebp,esp 将esp的值传给edp
3.sub esp,0E4h esp-0E4h(相当于给main函数预留了一段空间)
4.push ebx 将ebx的值压栈
5.push esi 将esi的值压栈
6.push edi 将edi的值压栈
7.lea edi edi,[ebp+FFFFFF1Ch](加载有效地址,将 [ ] 中的地址加载到edi中)
该地址为,[ebp-0E4h](此地址是第三行的值)
8.mov ecx,39h 将39h这个值放入ecx中
9.mov eax,0CCCCCCCCh eax中加入0CCCCCCCCh中
10.rep stos dword ptr es:[edi] 从第7到9行,从edi地址开始向下ecx个的double字(4字节)全部变成eax中的值
11.mov dword ptr [ebp-8],0Ah 将0Ah(10)放在ebp-8的位置处
12.mov dword ptr [ebp-14h],14h 将14h(20)放在ebp-14h的位置处
13.mov dword ptr [ebp-20h],0 将0放在ebp-14h的位置处
14.mov eax,dword ptr [ebp-14h] 将ebp-14h的值放在eax中
15.push eax 将eax的值压栈
16.mov ecx,dword ptr [ebp-8] 将ebp-8的值放在ecx中
17.push ecx 将ecx的值压栈
18.call 00C210E1 将call指令的吓一条指令压栈(此时进入函数内部)
19.push ebp 将ebp的值压栈
20.mov ebp,esp 将esp的值传给edp
21.sub esp,0CCh esp-0CCh(相当于给main函数预留了一段空间)
22.push ebx 将ebx的值压栈
23.push esi 将esi的值压栈
24.push edi 将edi的值压栈
25.lea edi edi,[ebp+FFFFFF34h](加载有效地址,将 [ ] 中的地址加载到edi中)
该地址为,[ebp-0CCh](此地址是第三行的值)
26.mov ecx,33h 将33h这个值放入ecx中
27.mov eax,0CCCCCCCCh eax中加入0CCCCCCCCh中
28.rep stos dword ptr es:[edi] 从第7到9行,从edi地址开始向下ecx个的double字(4字节)全部变成eax中的值
29.mov dword ptr [ebp-8],0 将0放在ebp-8的位置处
30.mov eax,dword ptr [ebp+8] 将ebp+8的值放在eax中(10)
31.add eax,dword ptr [ebp+0Ch] 将ebp+0Ch的值加到eax中(30)
32.mov eax,dword ptr [ebp-8] 把ebp-8的值放在eax中(30)、
33.pop edi edi出栈
34.pop esi esi出栈
35.pop ebx ebx出栈
36.mov esp,ebp 将ebp给esp
37.pop ebp 将弹出的值存入ebp中
38.ret 跳到此时从站栈顶弹出的地址处
39.add esp,8 将esp+8,即esp指向esp+8处,此时相当于将第15和17步的值弹出,空间归还给系统
40.mov dword ptr [ebp-20h],eax 将eax(30)中的值放到ebp-20h(变量c)中
具体回答的问题:
a、局部变量是怎么创建的?
给函数创建好栈帧空间后在该栈帧空间中给局部变量分配一部分空间。
b、为什么局部变量的值是随机的
当局部变量为初始化时,相当于使用的值是随机返给的值。
c、函数是怎么传参的,传参顺序是怎样的
在未调用函数的时候,就将参数push在main()函数的后边,传参的顺序是从右向左push的。
d、形参和实参是什么关系
形参和实参在值上是相同的,在空间上是相对独立的,所以说形参是实参的临时拷贝
e、函数调用结束如何返回
在调用之前就已经将call下一条指令的地址压入栈中,并且将调用的上一个函数的edp的值压入,在返回时依据这两个值来返回。
注:
a、函数传参是从右向左传的,由31可知形参是实参的一份临时拷贝;
b、寄存器是集成在CPU上的。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站名称:【C语言初阶】函数栈帧的创建和销毁-创新互联
新闻来源:http://azwzsj.com/article/dogdhc.html