call stack详解:
调用堆栈:调用堆栈是一个方法列表,按调用顺序保存所有在运行期被调用的方法。
栈:在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
当发生函数调用的时候,栈空间中存放的数据是这样的:
  1、调用者函数把被调函数所需要的参数按照与被调函数的形参顺序相反的顺序压入栈中,即:从右向左依次把被调函数所需要的参数压入栈;
  2、调用者函数使用call指令调用被调函数,并把call指令的下一条指令的地址当成返回地址压入栈中(这个压栈操作隐含在call指令中);
  3、在被调函数中,被调函数会先保存调用者函数的栈底地址(push ebp),然后再保存调用者函数的栈顶地址,即:当前被调函数的栈底地址(mov ebp,esp);
  4、在被调函数中,从ebp的位置处开始存放被调函数中的局部变量和临时变量,并且这些变量的地址按照定义时的顺序依次减小,即:这些变量的地址是按照栈的延伸方向排列的,先定义的变量先入栈,后定义的变量后入栈;
  所以,发生函数调用时,入栈的顺序为:
  参数N
  参数N-1
  参数N-2
  .....
  参数3
  参数2
  参数1
  函数返回地址
  上一层调用函数的EBP/BP
  局部变量1
  局部变量2
  ....
  局部变量N
解释:
  首 先,将调用者函数的EBP入栈(push ebp),然后将调用者函数的栈顶指针ESP赋值给被调函数的EBP(作为被调函数的栈底,mov ebp,esp),此时,EBP寄存器处于一个非常重要的位置,该寄存器中存放着一个地址(原EBP入栈后的栈顶),以该地址为基准,向上(栈底方向)能 获取返回地址、参数值,向下(栈顶方向)能获取函数的局部变量值,而该地址处又存放着上一层函数调用时的EBP值;
  一般而言,SS: [ebp+4]处为被调函数的返回地址,SS:[EBP+8]处为传递给被调函数的第一个参数(最后一个入栈的参数,此处假设其占用4字节内存)的 值,SS:[EBP-4]处为被调函数中的第一个局部变量,SS:[EBP]处为上一层EBP值;由于EBP中的地址处总是"上一层函数调用时的EBP 值",而在每一层函数调用中,都能通过当时的EBP值"向上(栈底方向)能获取返回地址、参数值,向下(栈顶方向)能获取被调函数的局部变量值";
  如此递归,就形成了函数调用栈;
  函数内局部变量布局示例:
  #include <stdio.h>
  #include <string.h>
  struct C
  {
  int a;
  int b;
  int c;
  };
  int test2(int x, int y, int z)
  {
  printf("hello,test2\n");
  return 0;
  }
  int test(int x, int y, int z)
  {
  int a = 1;
  int b = 2;
  int c = 3;
  struct C st;
  printf("addr x = %u\n",(unsigned int)(&x));
  printf("addr y = %u\n",(unsigned int)(&y));
  printf("addr z = %u\n",(unsigned int)(&z));
  printf("addr a = %u\n",(unsigned int)(&a));
  printf("addr b = %u\n",(unsigned int)(&b));
  printf("addr c = %u\n",(unsigned int)(&c));
  printf("addr st = %u\n",(unsigned int)(&st));
  printf("addr st.a = %u\n",(unsigned int)(&st.a));
  printf("addr st.b = %u\n",(unsigned int)(&st.b));
  printf("addr st.c = %u\n",(unsigned int)(&st.c));
  return 0;
  }
int main(int argc, char** argv)
  {
  int x = 1;
  int y = 2;
  int z = 3;
  test(x,y,z);
  printf("x = %d; y = %d; z = %d;\n", x,y,z);
  memset(&y, 0, 8);
  printf("x = %d; y = %d; z = %d;\n", x,y,z);
  return 0;
  }
  打印输出如下:
  addr x = 4288282272
  addr y = 4288282276
  addr z = 4288282280
  addr a = 4288282260
  addr b = 4288282256
  addr c = 4288282252
  addr st = 4288282240
  addr st.a = 4288282240
  addr st.b = 4288282244
  addr st.c = 4288282248
  a = 1; b = 2; c = 3;
  a = 0; b = 0; c = 3;
  示例效果图:
该图中的局部变量都是在该示例中定义的;

这个图片中反映的是一个典型的函数调用栈的内存布局;

访问函数的局部变量和访问函数参数的区别:
  
局部变量总是通过将ebp减去偏移量来访问,函数参数总是通过将ebp加上偏移量来访问。对于32位变量而言,第一个局部变量位于ebp-4,第二个位于ebp-8,以此类推,32位局部变量在栈中形成一个逆序数组;第一个函数参数位于ebp+8,第二个位于ebp+12,以此类推,32位函数参数在栈中形成一个正序数组。

call stack详解相关推荐

  1. Linux 存储 Stack详解

    (未完待续,持续更新中) 目录 序言 0 存储设备 0.1 机械盘 0.2 SSD 0.3 NVDIMM 1 VFS 1.0 基础组件 1.0.1 iov_iter 1.0.2 iomap 1.1 i ...

  2. Vector和Stack详解

    一.学习Vector和Stack之前先学习ArrayList ArrayList详解_Allence的博客-CSDN博客一.介绍ArrayList是以什么数据结构实现的ArrayList底层的数据结构 ...

  3. C++ STL 之堆栈(后进先出) stack 详解

    文章目录 Part.I Attention Part.II Funciton Part.III Code Part.I Attention stack<T>容器适配器的数据是以 LIFO ...

  4. Java中Stack详解

    前言 开发过程中经常会用到集合,在不用思考的情况下,集合我们肯定是用ArrayList,HashMap,特别点的时候会用到 HashSet.但是,这几个集合类真的是万能的么?针对不同的开发场景,我们需 ...

  5. 【STL】C++ STL之stack详解

    返回主目录 stack 1. 介绍 栈为数据结构的一种,是STL中实现的一个先进后出,后进先出的容器. 就像火车进入没有出口的隧道一样,隧道是stack栈容器,火车车厢是入栈元素,火车头先进去,火车尾 ...

  6. Tasks and Back stack 详解

    原文地址:http://developer.android.com/guide/components/tasks-and-back-stack.html 一个应用往往包含很多activities.每个 ...

  7. tf.stack() 详解

    tensorflow用于矩阵拼接的方法:tf.stack() 个人参考感觉还不错的一个理解(tf.stack() 和 tf.concat()的区别):https://blog.csdn.net/Gai ...

  8. java list 在头部添加6_【Java提高十六】集合List接口详解

    在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!java中集合大家族的成员实在是太丰富了,有常用的ArrayList. ...

  9. torch.stack(), torch.cat()用法详解

    torch.stack(), torch.cat()用法详解 if __name__ == '__main__':import torchx_dat = torch.tensor([[1, 2], [ ...

  10. np.stack()函数详解 ==>堆叠 【类似于torch.stack()】

    目录 1.来看看axis=0时,它是如何进行堆叠的:(按矩阵进行堆叠) 2.再来看看axis=1的时候:(按行进行堆叠) 3.当axis=2时(按列的的元素进行堆叠,先堆叠三个矩阵的第0个元素0,12 ...

最新文章

  1. Go 分布式学习利器(18)-- Go并发编程之lock+WaitGroup实现线程安全
  2. 中国科学院空天信息研究院苏州分院面试——总结
  3. 对python中浅拷贝和深拷贝分析详细介绍
  4. DI 之 3.4 Bean的作用域(捌)
  5. 牛客题霸 [判断一个链表是否为回文结构] C++题解/答案
  6. 容器编排技术 -- Kubernetes 为 Namespace 设置最小和最大内存限制
  7. Asp.Net前台调用后台变量
  8. log4j日志文件 log4j.xml log4j.properties配置
  9. linux centeros下Redis的安装
  10. 今天我的MSN提示升级了
  11. matlab中gama,matlab积分结果中的gamma()函数参数问题,急求解答!!!
  12. python的拼音库是什么意思_Python 中拼音库 PyPinyin 的用法!这个库有点意思哈!...
  13. 威廉希尔赔率分析和结论
  14. 通过FinalShell打通ssh隧道
  15. Spring 注解 属性赋值与自动注入装配
  16. No suspicious code found. 1 files processed in 'File '
  17. jmeter分布式报错,Error in rconfigure() method java.rmi.ConnectException: Connection refused to ho st
  18. Excel数据导入到hbase实战
  19. JAVA计算机毕业设计学生学籍信息管理系统Mybatis+源码+数据库+lw文档+系统+调试部署
  20. GBN,SR,TCP协议实现可靠数据传输的原理

热门文章

  1. vs2008激活、序列号
  2. 并行化:你的高并发大杀器
  3. php中怎么设置透明背景图片,css怎样设置背景透明
  4. sakai mysql_sakai 开发环境搭建(一)
  5. DLL注入explorer.exe进程
  6. 香港警方据线报捣破9个非法赌档 共拘捕114人
  7. OpenDrive里XY和ST
  8. matlab db5是什么小波,3、代码 - matlab小波分析步骤是什么
  9. 用javacv提取视频中的音频数据
  10. ae效果英文版翻译对照表_AE特效菜单中英文对照