函数调用过程,栈帧的创建和销毁
来源:互联网 发布:淘宝暴力引流软件 编辑:程序博客网 时间:2024/06/06 21:44
原码如下:
#include <stdio.h> #pragma warning (disable:(4996))int Add(int x,int y) { int sum = 0; sum = x+y; return (sum); } int main() { int a = 2; int b = 3; int ret = 0; ret = Add(a,b); return 0; }
基本的汇编指令:
esp:esp寄存器里存储的是在调用函数之后,栈的栈顶。并且始终指向栈顶。
ebp:ebp寄存器里存储的是是栈的栈底指针,通常叫栈基址,这个是一开始进行函数调用之前,由esp传递给ebp的。(在函数调用前你可以这么理解:esp存储的是栈顶地址,也是栈底地址。)
push:压入操作,把一个32位的操作数压入堆栈中,这个操作在32位机中会使得esp被减4(字节),esp通常是指向栈顶的,这里顶部是地址小的区域,那么,压入堆栈的数据越多,esp也就越来越小
mov:数据传送。第一个参数是目的操作数,第二个参数是源操作数,就是把源操作数拷贝到目的一份。
sub:创建空间。
lea:load effective address 加载有效地址。
rep stos:重复指令
转到反汇编之后:
1.当_tmainCRTStartup 还没有调用main函数时,esp,ebp共同维持并为_tmainCRTStartup开辟一个空间,
如下图所示:
2.开始调用main函数:
汇编代码如下:
(1)执行第一条指令: push ebq//压栈,将ebp放入栈顶,而esp始终指向栈顶,如下图所示:
(2)执行第二条指令:mov ebp,esp//将esp赋予ebp,ebp和esp指向同一位置,如下图所示:
(3)执行第三条指令:sub esp,0E4h //将esp减去0E4h,0E4h是十六进制数,由于开辟的栈空间由高到低,所以esp往上走0E4h,如下图所示:
(4)执行指令:push ebx
push esi
push edi//ebx,esi,edi三个寄存器进行压栈,main空间增大,如下图所示:
(5)执行指令:lea edi,[ebp-0E4h] //[ebp-0E4h]是ebx,将ebx的地址传到edi中
mov ecx,39h //将39h传到ecx寄存器中
mov eax,0CCCCCCCCh //将0CCCCCCCCh传到eax寄存器中
rep stos dword ptr es:[edi] //将栈上[ebp-0E4h]的位置开始向高地址的内存赋值0CCCCCCCCh,次数为0x39,0CCCCCCCCh代表未初始化。
如下图所示:
以上是main函数的调用。
以下是自己写的代码,转换成汇编代码:
指令 : mov dword ptr [a],2 /*dword 双字 就是四个字节ptr pointer缩写 即指针,[]里的数据是一个地址值,这个地址指向一个双字型数据。即将地址a指向的四字节数据2移动到ebp-4*/
指令:mov dword ptr [b],3 //与上指令功能相似
指令: mov dword ptr [ret],0 //与上指令功能相似
指令:mov eax,dword ptr [b] //将变量b的值赋给eax
push eax //将eax压栈
指令:mov ecx,dword ptr [a]
push ecx
指令:call @ILT+215(_Add) (0F810DCh) //call指令下一条指令的地址
指令效果如图所示:
Add函数汇编代码如下:
指令:
push ebp //ebp压栈
mov ebp,esp //将esp传给ebp
sub esp,0CCh //给add函数开辟空间
push ebx
push esi
push edi //将ebx,esi,edi三个寄存器压栈,add函数空间增大
lea edi,[ebp-0CCh]
mov ecx,33h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi] //将从[ebp=0CCh]的地址位置开始向高地址内存空间赋值0CCCCCCCCh ,次数为33h
mov dword ptr [sum],0 //给sum赋值0
mov eax,dword ptr [x] //将x处的值传给eax
add eax,dword ptr [y]
mov dword ptr [sum],eax //将eax的值传给sum
mov eax,dword ptr [sum] 将sum的值存在寄存器eax中
指令效果如图:
出栈汇编代码:
指令:
pop edi
pop esi
pop ebx //三个寄存器出栈
mov esp,ebp //将esp栈顶下移
pop ebp //将ebp出栈,此时下面还有一个ebp
ret //回到call指令的下一条指令
add esp,8//esp向下跳两格
mov dword ptr [ret],eax //将eax的值传给ret处。
xor eax,eax //异或运算,相同返回0,相反返回1;
指令效果如下:
函数的调用过程,栈帧的创建和销毁已经完成。
- 函数的调用过程,栈帧的创建和销毁
- 函数的调用过程,栈帧的创建和销毁。
- 函数的调用过程,栈帧的创建和销毁
- 函数的调用过程,栈帧的创建和销毁。
- 函数的调用过程,栈帧的创建和销毁
- 函数的调用过程,栈帧的创建和销毁
- 函数调用过程,栈帧的创建和销毁
- 函数调用过程,栈帧的创建和销毁
- 函数的调用过程,栈桢的创建和销毁
- 函数的调用过程,栈桢的创建和销毁。
- 函数的调用过程、栈帧的创建以及销毁
- 函数的调用过程,栈帧的创建与销毁
- 【C】函数的调用过程,栈帧的创建和销毁
- 谈谈函数的调用过程,栈帧的创建和销毁。
- 函数的调用过程(栈帧的创建和销毁)
- 浅谈函数的调用过程,栈帧的创建和销毁,附图讲解
- 函数调用的具体过程以及栈帧的创建和销毁
- 第三篇 函数的调用过程 栈帧的创建和销毁
- 图片验证码部分代码整理
- SpringBoot与Dubbo的整合
- codeforces 120A Elevator
- JavaScript hasOwnProperty() 函数详解
- Linux中Netfilter框架
- 函数调用过程,栈帧的创建和销毁
- 变量对象(Variable Object)
- Windows平台kafka环境的搭建
- windows下的使用别人编译好的库文件进行安装xgboost
- java基础知识总结
- TensorFlow下构建高性能神经网络模型的最佳实践
- Zookeeper启动异常:Error contacting service. It is probably not running.
- ssh免密登录
- 机器学习-随机森林(randomForest)模型的优化策略