函数调用过程中函数栈详解
当进程被加载到内存时,会被分成很多段
- 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写,如果发生写操作则会提示segmentation fault
- 数据段:保存初始化的全局变量和静态变量,可读可写不可执行
- BSS:未初始化的全局变量和静态变量
- 堆(Heap):动态分配内存,向地址增大的方向增长,可读可写可执行
- 栈(Stack):存放局部变量,函数参数,当前状态,函数调用信息等,向地址减小的方向增长,可读可写可执行
- 环境/参数段(environment/argumentssection):用来存储系统环境变量的一份复制文件,进程在运行时可能需要。例如,运行中的进程,可以通过环境变量来访问路径、shell 名称、主机名等信息。该节是可写的,因此在缓冲区溢出(buffer overflow)攻击中都可以使用该段
寄存器
EAX:累加(Accumulator)寄存器,常用于函数返回值
EBX:基址(Base)寄存器,以它为基址访问内存
ECX:计数器(Counter)寄存器,常用作字符串和循环操作中的计数器
EDX:数据(Data)寄存器,常用于乘除法和I/O指针
ESI:源变址寄存器
DSI:目的变址寄存器
ESP:堆栈(Stack)指针寄存器,指向堆栈顶部
EBP:基址指针寄存器,指向当前堆栈底部
EIP:指令寄存器,指向下一条指令的地址
入栈push和出栈pop
push ebp就等于将ebp的值保存到栈中,并且将当前esp下移
pop ebp就等于将ebp的值从栈中取出来,将ebp指向这个值
下面用一个例子来讲函数调用过程中栈的变化
int sum(int _a,int _b)
{int c=0;c=_a+_b;return c;
}int main()
{int a=10;int b=20;ret=sum(a,b);return 0;
}
main函数的栈在调用之前如图:
Ok现在讲一讲ret=sum(a,b);的执行过程
Step 1:
函数参数从右至左入栈
Step 2:
ret=sum(a,b);
call @ILT+0(sum) (00401005) call指令实际上分两步
push EIP 将下一条指令入栈保存起来
esp-4 esp指针下移
Step 3:
push ebp 将main函数基指针入栈保存
mov ebp esp 将esp的值存入ebp也就等于将ebp指向esp
sub esp 44H将esp下移动一段空间创建sum函数的栈栈帧
Step 4:
push ebx
push esi
push edi
lea edi,[ebp-44h] 从ebp-44h的地方开始拷贝
mov ecx,11h 拷贝11次
mov eax,0CCCCCCCCh 拷贝内容为0CCCCCCCCh
rep stos dword ptr [edi] 每次拷贝双字
Step 5:
int c = 0;
mov dword ptr [ebp-4],0 将sum的局部变量c放入[ebp-4]的空间内
Step 6:
执行函数操作
Step 7:
return c = 0;
mov eax,dword ptr [ebp-4] 将返回值(变量c所在的地址的内容)放入eax寄存器保存住
Step 8:
pop edi //将之前入栈的值重新返回给edi寄存器
0040104C pop exi 将之前入栈的值重新返回给exi寄存器
0040104D pop ebx 将之前入栈的值重新返回给ebx寄存器
Step 9:
mov esp ebp //将ebp的值赋给esp,也就等于将esp指向ebp,销毁sum函数栈帧
Step 10:
pop ebp //ebp出栈,将栈中保存的main函数的基址赋值给ebp
Step 11:
ret //ret相当于pop eip 就是把之前保存的函数返回地址(也就是main函数中下一条该执行的指令的地址)出栈
Step 12:
add esp,8 //此时若传入sum函数的参数已经不需要了,我们将esp指针上移
此时函数整个调用过程就结束了,main函数栈恢复到了调用之前的状态
函数调用过程中函数栈详解相关推荐
- C语言 -- string.h中函数功能详解与手动实现 - 02(常用函数memcpy、memmove、strcpy、strdup、strcat、strtok...)
内容预览 3.5.搬迁类型 --- 函数功能详细说明 :将内存空间中内容移动.复制到另一内存空间 3.6.搬迁类型 --- 函数功能测试与手动实现 3.6.1.memcpy.memccpy 3.6.2 ...
- 函数调用过程中的栈帧结构及其变化
前言:本文旨在从汇编代码的角度出发,分析函数调用过程中栈帧的变化. 栈帧的简单介绍: 当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分栈称为栈帧.下图描述了栈帧的 ...
- oracle安装过程中内核参数详解
转载网址:https://www.cnblogs.com/colben/p/4120439.html 在安装Oracle的时候需要调整linux的内核参数,但是各参数代表什么含义呢,下面做详细解析. ...
- 汇编中函数调用过程中,栈到底是怎样变化的?call、ret、指令分别有什么样的作用?
1.栈帧的结构:栈帧主要包括三个部分:被保存的%bp,被保存的寄存器.本地变量等,参数区域 2.call指令的作用: 将程序下一条指令的位置的IP压入堆栈中: 转移到调用的子程序 3.ret指令的作用 ...
- C++ 函数调用过程中栈区的变化——(栈帧、esp、ebp)
C++ 函数调用过程中栈区的变化 1.C++ 函数调用过程中栈区的变化 1.1.程序的内存分布 1.2.函数调用过程中栈的变化解析 参考 1.C++ 函数调用过程中栈区的变化 1.1.程序的内存分布 ...
- python explode_pandas dataframe 中的explode函数用法详解
在使用 pandas 进行数据分析的过程中,我们常常会遇到将一行数据展开成多行的需求,多么希望能有一个类似于 hive sql 中的 explode 函数. 这个函数如下: Code # !/usr/ ...
- python中def func是什么意思_Python的函数参数详解
原标题:Python的函数参数详解 前言 Python中函数的参数可以分为两大类形参和实参~ def func(x, y): # x, y 就是形参 print(x, y) func(2, 3) # ...
- 数字图像处理:OpenCV-Python中的直方图均衡知识介绍及函数equalizeHist详解
一.引言 在<数字图像处理:直方图均衡(Histogram Equalization)的原理及处理介绍 >(链接:https://blog.csdn.net/LaoYuanPython/a ...
- python six模块详解_对python中的six.moves模块的下载函数urlretrieve详解
实验环境:windows 7,anaconda 3(python 3.5),tensorflow(gpu/cpu) 函数介绍:所用函数为six.moves下的urllib中的函数,调用如下urllib ...
最新文章
- 通过 PhxPaxos 了解 Paxos 原理
- python输入数据的维度_keras分类模型中的输入数据与标签的维度实例
- Springcloud中的region和zone的使用
- 【转】Linux ln(link) 命令详解
- error_logs
- textarea怎么占满整个td_保健品为什么偏偏盯上老人?作为子女,应怎么面对老人狂买保健品...
- 好用又被遗忘的Char,String 方法
- java keytool 使用总结(转)
- 2022 基于SpringBoot/SSM的脚手架租赁系统
- html5小游戏代码-2048游戏
- python中爬取网页数据时中文乱码的解决方法
- 【cpu如何超频及cpu超频作用】
- 质量功能展开QFD成功案例解析
- 正大美欧4的主账户关注什么数据?
- C++重温笔记(一): C++再初识
- Mac苹果电脑 安装virtualBox
- 解决sourcetree修改账号和fatal:Authentication failed
- Mysql 脚本创建触发器报错 1064 42000
- JAVA开发方向和就业方向
- 自动生成fbi代码网站
热门文章
- html里面点击重置按钮无反应,点击重置按钮后没反应.
- 数字签名标准(DSS)
- MacBook Pro设置外接显示器竖屏显示,2k 字体小
- Flutter图片添加水印功能,Flutter保存Widget为图片
- Mac 下erlang及rabbitmq安装
- opencv打开mp4文件_OpenCV 实现播放本地mp4视频或远程服务mp4视频
- 简易数字示波器,DDS信号源的设计方案
- Uncaught TypeError: Cannot read property ‘length‘ of null解决经验贴
- Web渗透攻击之vega
- 非线性微分方程有限差分解法