函数的调用过程(栈帧)
来源:互联网 发布:线切割控制编程系统 编辑:程序博客网 时间:2024/05/21 14:50
我们研究一下函数的调用过程,首先看一段简单的代码:
#include<stdio.h>int add(int x,int y){ int z = 0; z = x + y; return z;}int main(){ int a = 10; int b = 20; int ret = add(a,b); printf("ret = %d\n",ret); return 0;}
EBP和ESP是寄存器,EBP指向栈底,ESP指向栈顶。程序的入口是main函数,进来以后,
执行 int a = 10;int b = 20。为变量a,b创建一个空间,先给a创建,再给b创建。a的地址比b的地址高。
临时变量在当前栈的栈顶位置,即esp的位置。函数参数赋值的顺序是右右往左,这是由栈帧决定的。
move eax,dword ptr [ebp-8]。[ebp-8]就是指b ,把b move到eax寄存器当中,eax是cpu里面的寄存器,然后把eax里的b push到栈中,此时ESP寄存器指向b的位置.
move ecx,dword ptr[ebp-4]。再把a压入栈中,ESP再移动指向a。这里[ebp-4]指a,(-4)指当前位置与首地址的偏移量因,所以a的地址比b的地址高。
接下来
0040108E call @ILT+0(my_add) (00401093)
call的作用是把下一个地址压入当前的栈顶位置,即a的地址下面,比a的地址低。
然后是跳转jmp指令,跳转到my_add函数里面。
move ebp,esp
esp指向哪,ebp就指向哪。 esp-44h
esp变小,往下移。
这个时候产生新的ebp和新的esp,产生my_add的栈帧。eip变成my_add的寄存器。
在my_add函数里面
int z = x + y;
move eax,dword ptr[ebp+8]
就是把a放到eax。 add eax,dword ptr[ebp+0Ch]
这里就把a和b加起来。 move dword ptr[ebp-4],eax
把加起来的结果放到eax里面。
return z;
就是下面的指令:
move eax,dword ptr[ebp-4]
把返回值放在eax里面。
接下来:
move esp,ebp
就是说,ebp指向哪里,esp就指向哪里。
pop ebp
把栈顶的内容弹出来,即把main ebp移到ebp的位置,这样子就回到了最开始的位置。
把栈顶放到eip的位置,就回到了main函数。这个时候执行ret指令:
ret
这个指令走完过后,esp变成00401093。
在main函数里面
add esp+8
espz指向图示位置,过程调用完成。
- 函数调用过程的真实情况(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 关于函数的调用过程(栈帧)
- 小结 | 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程(栈帧)
- 函数的调用过程--栈帧
- 函数调用的过程
- 函数调用的过程
- 函数调用的过程
- 函数的调用过程
- 函数的调用过程
- Vulkan规范:第四章 4.1
- 单链表-头插法、尾插法和基本运算
- okhttp学习
- Spring学习笔记之通过注解配置Bean(1)
- 文章标题
- 函数的调用过程(栈帧)
- Error:(17, 24) 警告: Application namespace for attribute app:url will be ignored.
- Vulkan规范:第四章 4.2
- Java设计模式--享元模式
- Java SE 7 Archive Downloads
- 深入C/C++之基于CheckStackVars的安全检查(VS2008)
- python: bin函数
- VS2017控制台窗口下控制台输出中文乱码
- Vulkan规范:第四章 4.3