c语言函数调用过程中栈的工作原理理解
差不多每个程序员都知道,函数调用过程,就是层层入栈出栈的过程。
那么这个过程中的详细的细节是什么样子的呢?
阅读了以下几篇文章之后,对整个过程基本理解了:
C函数调用过程原理及函数栈帧分析
阅读经典——《深入理解计算机系统》04
函数返回值与栈
针对自己的理解,做个记录:
(一般的操作系统)
- 每个函数都是一个栈结构,有一个栈底指针ebp和栈顶指针esp。栈底指针在函数的执行过程中是不变的,栈顶指针会随着函数的执行动态的增大。
- 在操作系统中,栈底在地址最大的地方,栈是向地址小的方向增长的。所以在栈中,申请空间时,是将栈顶指针esp向下移动,即减去一个大小。
- 函数的层层调用,就形成了连续的栈空间。
- 函数在调用被调用函数时,会将需要传递的参数由从右向左的顺序入栈。被调用函数会根据这个关系去对应的位置取参数。
- 将参数入栈之后,还会将下一条指令的地址入栈。即从被调用函数返回之后,应该执行哪一条指令。
- 跳转至被调用函数。被调用函数需要将当前的栈底指针ebp的值入栈,因为当被调用函数执行完毕之后,需要恢复调用函数的栈空间。并将ebp寄存器的值设为当前函数的栈空间的底部对应的地址,即当前esp的值。
- 被调用函数执行时,根据参数的传入顺序便可以计算出参数相对于ebp指针的位置,从而获取变量的值。
- 被调用函数执行完毕后,如果有返回值,会将返回值存入eax寄存器中。并释放申请的栈空间,恢复ebp和esp的值。从而使被调用函数能够正常执行。
- 将指针寄存器指向调用函数压入栈中的返回地址。
- 调用函数继续执行,如果需要结果,则从eax寄存器中获取
疑问:
假设栈的地址空间为0x20-0x11。
那么
ebp=0x20
esp=0x10?
如果入栈一个数据(假设4个字节)时,是插入一个数据到0x10,0xf,0xe,0xd。这4个地址,并将esp设置为0xc?
即ebp指向栈空间开始的字节。esp指向栈顶端的下一个字节?
c语言函数调用过程中栈的工作原理理解相关推荐
- 函数调用过程,栈帧的一点理解
栈帧图例一张 寄存器理解 程序寄存器组是唯一能被所有函数共享的资源.虽然某一时刻只有一个函数在执行,但需保证当某个函数调用其他函数时,被调函数不会修改或覆盖主调函数稍后会使用到的寄存器值.因此,IA3 ...
- C++ 函数调用过程中栈区的变化——(栈帧、esp、ebp)
C++ 函数调用过程中栈区的变化 1.C++ 函数调用过程中栈区的变化 1.1.程序的内存分布 1.2.函数调用过程中栈的变化解析 参考 1.C++ 函数调用过程中栈区的变化 1.1.程序的内存分布 ...
- 函数调用过程中函数栈详解
当进程被加载到内存时,会被分成很多段 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写,如果发生写操作则会提示segmentation fault 数据段:保存初始化的全局变量和静 ...
- 函数调用过程中的栈帧结构及其变化
前言:本文旨在从汇编代码的角度出发,分析函数调用过程中栈帧的变化. 栈帧的简单介绍: 当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分栈称为栈帧.下图描述了栈帧的 ...
- 函数调用 压栈的工作原理
1.开篇 本篇文章着重写的是系统中栈的工作原理,以及函数调用过程中栈帧的产生与释放的过程,有可能名字过大,如果不合适我可以换一个名字,希望大家能够指正,小丁虚心求教!如果有哪里写的不清楚的或者错 ...
- C语言编程宏定义的优缺点,C语言重要知识点总结(二)--内存结构、函数调用过程(栈帧)、宏的优缺点以及##和#的使用...
一.内存结构 内存大致可以分为四个部分:代码段,静态存储区,堆,栈. 具体划分如下图所示: 栈:在执行函数时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束后会自动释放内存.栈内存的分配运算 ...
- 从函数调用过程中的堆栈变化理解缓冲区溢出
一.说明 本来是想直接写一个缓冲区溢出的例子,但是一是当前编译器和操作系统有溢出的保护措施没有完全弄清怎么取消,二是strcpy等遇到00会截断需要进行编码这比较难搞,所以最终没有实现. 但已经双看了 ...
- c语言函数调用参数调用的太少,浅谈C语言函数调用参数压栈的相关问题
参数入栈的顺序 以前在面试中被人问到这样的问题,函数调用的时候,参数入栈的顺序是从左向右,还是从右向左.参数的入栈顺序主要看调用方式,一般来说,__cdecl 和__stdcall 都是参数从右到左入 ...
- c语言函数参数压栈,函数调用压栈 浅谈C语言函数调用参数压栈的相关问题
想了解浅谈C语言函数调用参数压栈的相关问题的相关内容吗,在本文为您仔细讲解函数调用压栈的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:函数调用压栈,下面大家一起来学习吧. 参数入栈的顺序 ...
最新文章
- ACM训练小结-2018年6月16日
- 3-3-完全二叉树结点数
- 在 ASP.NET 中使用 HTTPHandler 实现 Front Controller
- 30种优化查询速度的方法
- 如何做出受欢迎的字体排版风格?
- python进制转化大全
- usb转rj45_毕亚兹ZH5网卡转接口评测:3HUB接口+1网口,好用还便宜
- 谈新手对CString的使用
- CSS浏览器兼容性与解决方法
- java对象布局查看工具_Java 查看对象布局工具 - Java Object Layout
- 01-windows下 Rserve安装
- axure 发布 主页_车队如何在黑鸟APP发布同城活动?教程来了!
- 动态ip、静态ip、pppoe拨号的区别
- MTK平台调试加密芯片ATSHA204A
- 程序员求职之道(《程序员面试笔试宝典》)之民间的企业排名的可信度到底有多大?...
- sprintf()出错,使用strcat()正确
- python车流量检测车流统计车辆计数yolov5 deepsort车流检测
- Vivado ROM IP核
- 推荐收藏!200个源数据网站全给你!
- oracle vm 鼠标切换,VirtualBox的Linux虚拟机文本模式和图形模式的切换问题