目录

  • esp
  • ebp
  • 上一层ebp和本层ebp的保存方法
  • call 函数的参数在栈中的位置
  • 总结函数参数和局部变量
  • od中查看 栈空间的返回到子程序的情况

esp

call执行跳入子程序以后栈顶寄存器,一直指向栈顶

ebp

call执行过跳入子程序以后,一直指向栈底

看下面例子模拟一个有2个参数的函数.例如函数参数1是1, 参数2是2

push 2 //参数2
push 1 //参数1
call 子程序地址

//子程序开始以后的栈的内容操作如下图红框出是call的下一条语句的地址,这个地址会被首先压入栈顶,如下图

压入栈顶之后如下图

上面图栈顶显示是:"返回到"这个就是外面call的下一条语句的地址 ,这样当子程序结束的时候可以通过retn语句的时候 找到call下面的语句,.因为retn语句,等于pop eip,然后cpu就会执行eip里的语句

上一层ebp和本层ebp的保存方法

首先要明白为什么要保存上一层ebp
ebp是用来保存本层call的栈底位置的寄存器,每次进入call之后,会保存本层call子程序的栈底,加入不保存上一层的ebp,那么本层call执行结束以后。ebp因为保存了本层的栈底,就改变了,上一层的栈底在进入本层call之前是被保存到ebp里面的,但是结束本层靠以后就被改变了,那么回到上一层,通过ebp就找不到栈底了。所以上一层call的ebp必须在本层靠进来的时候就保存,保存方法就是在一进来call就push ebp, 当在返回之前的上一句,再pop ebp,这样上一层的ebp就被保存下来了,在call 内的子程序一般如下格式保存ebp .注意下图中的mov ebp, esp,是保存本层的栈底。因为一进来本层的call,压入之前ebp以后,栈顶往上移动一个元素,esp - 4,然后现在开始的栈顶被认为也是栈底。

push ebp //子程序外侧的ebp入栈,目的是保存外面的ebp,因为外面也有call,外层的call的栈底保存在ebp里面,出站
mov ebp,esp //因为此时的esp是栈顶,同时也是栈底,所以用ebp栈底寄存器保存栈底
一直到遇到retnebp都不会变化,因为ebp就是用来保存本层call的栈底的pop ebp
retn

保存本层和上一层ebp的过程在 od中的截图如下:

下图是retn时候,还原上一层ebp的执行结果截图:pop ebp以后,就把最开始进来就保存的上一层ebp还原了

call 函数的参数在栈中的位置

看下面图是cpu执行到call里面,然后执行完push ebp mov ebp,esp之后栈里面的情况


以内给本层ebp复制以后,ebp在本层不在改变,所以,call的参数位置也是固定的,位置如下:
ebp+4是返回到
ebp+8是参数1
ebp+c 是参数2
ebp +10 参数3
总结是 ebp+ 8是第一个参数,之后每次+4,按照十六进制表示
子程序里面的push是局部变量,如下图的2处push esi

下面图是 在栈空间通过sub esp改变了栈顶以后再分配局部变量,下面图让 sub esp 28,栈顶向上移动28再往栈顶push局部变量

总结函数参数和局部变量

esp在子程序头部

  • esp + 4, + 8 + c都是 函数参数,是在call外push进栈的.
  • esp - 4, - 8 等,只要是减的,可能是局部变量,不是局部变量的情况是,在申请局部变量之前,执行了push操作,让esp减少了.或者执行了 sub esp ,4等 操作,让esp减少了.

od中查看 栈空间的返回到子程序的情况

  • 在返回到子程序的上面,就是局部变量
  • 在返回到子程序的下面,是call外传进来的参数
    如下图:

汇编中esp和ebp在函数栈空间的保存和变化 call的参数和局部变量的关系详解相关推荐

  1. php判断参数_php检查函数必传参数是否存在的实例详解

    php检查函数必传参数是否存在的实例详解 在php实际编程中,接口经常会接收到前端传来的参数,其中有些参数不是必传的,有些参数是必传的,如何"检查函数必传参数是否存在"呢?为了解决 ...

  2. 好程序员前端教程之JavaScript闭包和匿名函数的关系详解...

    好程序员前端教程之JavaScript闭包和匿名函数的关系详解 本文讲的是关于JavaScript闭包和匿名函数两者之间的关系,从匿名函数概念到立即执行函数,最后到闭包.下面一起来看看文章分析,希望你 ...

  3. Java中常见RuntimeException与其他异常表及Exception逻辑关系详解

    Java中常见RuntimeException与其他异常表及Exception逻辑关系详解 前言 常见`RuntimeException` 其他错误类型 `Error`类 `Exception`类 E ...

  4. 汇编: 在代码中安排自己定义的数据,栈空间

    assume cs:codecode segmentdw 1,2,3,4,5,6,7,8 ; 我们自定义的数据 不是我们自定义的指令; d:define w:wordstart: mov bx,0mo ...

  5. python函数中可变参数的传递方式是_详解Python函数可变参数定义及其参数传递方式...

    Python函数可变参数定义及其参数传递方式详解 python中 函数不定参数的定义形式如下 1. func(*args) 传入的参数为以元组形式存在args中,如: def func(*args): ...

  6. double fun在c语言中是什么意思,编写函数 double fun(double x,double y),计算两参数平方差的绝对值,做为函数返回值....

    编写函数fun,函数首部为double fun(int n),其功能是计算S=1!+2!+3!... 6个答案 - 提问时间: 2011-10-13 - 6个赞 问题说明:"S=1!+2!+3!+.. ...

  7. linux getline函数用法,Linux文本处理三剑客之awk学习笔记05:getline用法详解

    getline用法详解 在默认情况下,awk支持从文件或者STDIN中读取数据.我们也可以使用getline来灵活读取数据,例如在main代码块执行过程中读取某个非待处理文件的数据,或者从某个读取某个 ...

  8. 在android中执行多个动画,Android上几种Animation和多个动画同时播放以ScaleAnimation应用详解...

    在API Demo的View->Animation下可以找到四个Animation的Demo,第一个3D Translate比较复杂,最后再讲,先讲第2个Interpolator.该Activi ...

  9. UML 中关系详解以及在visio中的表示

    http://www.cnblogs.com/kittywei/archive/2013/05/15/3079536.html Uml 关系主要有四大类: 依赖,关联,泛化,实现. 其中 依赖和关联是 ...

最新文章

  1. Spring Boot 使用slf4j+logback记录日志配置
  2. C#中字段、属性、只读、构造函数赋值、反射赋值的相关
  3. 膜拜大牛!HTTPS面试常问全解析,吊打面试官系列!
  4. Java 蓝桥杯 算法 和为T
  5. 持续集成:什么应该自动化?
  6. Flex里[Exclude]标签的作用:对外忽略/隐藏内部某对象
  7. Linux-HA 高可用开源方案 Keepalived VS Heartbeat 的选择
  8. 【Selenium】1.介绍 Selenium
  9. HFT-CNN:层级多标签分类,让你的模型多学习几次
  10. jsp文件上传图片到服务器
  11. HDMI的DDC是什么
  12. 小园丁与老司机_疲倦的园丁
  13. Java工程师胜任力素质模型,胜任力故事汇编C47│AspiringMinds:高潜力程序员的胜任力素质模型...
  14. 基于R的飞机航线数据可视化(行政区划)
  15. 黄金短线交易技巧是什么?
  16. 字符串中的转义字符(史上最详版)
  17. Win10安装nodejs 错误代码2502,2503
  18. springboot项目:老年教育学习系统fte91(java+VUE+Mybatis+Maven+Mysql)
  19. greendao 默认数据库db 生成路径,以及db文件导出
  20. 当前目录./和父目录../辨析

热门文章

  1. Flink之DataSet迭代计算
  2. python爬虫学习之路(二)re库的使用方法
  3. 带有数字钥匙的智能电动车已商用
  4. drag方法——>拖拽
  5. 如何分类保存下载京东商城无官方水印商品主图
  6. 超算计算机需要显卡吗,NVIDIA:中国超算性能世界第一认了 但省电我最强
  7. 这样写的文案可以激起欲望
  8. 1.0数据采集与预处理概述
  9. SSM框架之数据分页,模糊查询
  10. Linux怎么彻底删除用户