函数在实现过程内存中的压栈和出栈
关于函数在调用过程中的压栈和出栈问题在学习的时候就感觉很经典,对程序的把握可以提升一个台阶。
一.首先让我们写出一个简单的函数。(我是在vc6.0中实现,并不表示vs编译器底下不可以实现)。
#include<stdio.h>
int add(num1,num2)
{
int ret = 0;
ret = num1+num2;
return ret;
}
int main()
{
int num1 = 1;
int num2 = 2;
int ret = add(num1,num2);
printf("%d ",ret);
return 0;
}
1).需要声明是add函数中可以直接写成"return num1+num2",我在写博客的时候是故意写成这样,以便于后面的分析。
二.接下来,我们首先明确几个知识点。
1).栈
首先必须明确一点也是非常重要的一点,栈是向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,栈有栈底和栈顶,那么栈顶的地址要比栈底低。对x86体系的CPU而言,其中
---> 寄存器ebp(base pointer )可称为“帧指针”或“基址指针”,其实语意是相同的。
---> 寄存器esp(stack pointer)可称为“ 栈指针”。
要知道的是:
--->ebp 在未受改变之前始终指向栈帧的开始,也就是栈底,所以ebp的用途是在堆栈中寻址用的。
—>esp是会随着数据的入栈和出栈移动的,也就是说,esp始终指向栈顶。
2).
假设函数A调用函数B,我们称A函数为"调用者",B函数为“被调用者”则函数调用过程可以这么描述:
(1)先将调用者(A)的堆栈的基址(ebp)入栈,以保存之前任务的信息。
(2)然后将调用者(A)的栈顶指针(esp)的值赋给ebp,作为新的基址(即被调用者B的栈底)。
(3)然后在这个基址(被调用者B的栈底)上开辟(一般用sub指令)相应的空间用作被调用者B的栈空间。
(4)函数B返回后,从当前栈帧的ebp即恢复为调用者A的栈顶(esp),使栈顶恢复函数B被调用前的位置;然后调用者A再从恢复后的栈顶可弹出之前的ebp值(可以这么做是因为这个值在函数调用前一步被压入堆栈)。这样,ebp和esp就都恢复了调用函数B前的位置,也就是栈恢复函数B调用前的状态。
如下图所示
三.在明确了这些知识之后,让我们返回上面那个简单的函数。
1).首先来看看我画出的图。
上面的图片能够粗略的表现函数调用的过程。
2).
所产生的汇编代码:
上面两幅图片是mian函数的栈帧。
上面的图片是add函数的栈帧。
3).在liunx平台下的汇编代码
以上为本人在学习函数在内存中的操作的一些经验,当然,本人才疏学浅,上述肯定会有纰漏,若有读者发现,请联系我及时改正。谢谢!
转载于:https://blog.51cto.com/10799170/1715186
函数在实现过程内存中的压栈和出栈相关推荐
- c语言复制粘贴源码,c语言函数memccpy()如何复制内存中的内容实例源码介绍
c语言函数memccpy()如何复制内存中的内容实例源码介绍.引入的头文件:#include memccpy()函数定义:void * memccpy(void *dest, const void * ...
- java中push和pop指令的作用_汇编语言PUSH和POP指令(压栈和出栈)
汇编里把一段内存空间定义为一个栈,栈总是先进后出,栈的最大空间为 64K.由于 "栈" 是由高到低使用的,所以新压入的数据的位置更低,ESP 中的指针将一直指向这个新位置,所以 E ...
- Go语言_数据结构_栈(包括入栈和出栈,表达式的入栈出栈详细过程代码实现)
入栈和出栈代码实现如下: package main import ("fmt""errors" )//使用数组来模拟一个栈的使用 type Stack stru ...
- 【OpenGL】二十一、OpenGL 矩阵压栈与出栈 ( 不同类型矩阵变换先后顺序 | 渲染前不设置单位阵 | 压栈出栈原理分析 | 代码示例 )
文章目录 一.不同类型矩阵变换先后顺序 二.渲染前不设置单位阵 三.矩阵的压栈和出栈原理分析 四.矩阵的压栈和出栈代码示例 五.相关资源 一.不同类型矩阵变换先后顺序 对 OpenGL 中的 模型视图 ...
- C++ opengl 矩阵的压栈与出栈
矩阵的压栈与出栈 让两个重合的三角形,分开 程序运行截图如下: 伪代码如下: void Init() {//设置当前矩阵glMatrixMode(GL_PROJECTION); //设置为投影矩阵(对 ...
- 为什么二叉树的前序遍历和中序遍历对应入栈和出栈次序?
对一棵树或者子树进行先序或者中序遍历时入栈顺序相同. 都是根节点.左子树.右子树,(注意是入栈) 先序访问后入栈,中序出栈后访问, 则先序序列就是入栈顺序,中序序列就是出栈顺序. 卡特兰数应用之出栈次 ...
- 细谈 对象的初始化过程------内存中的实现过程?
今天对于内存的理解 又加深了一步: 对下面代码的理解: [html] view plaincopyprint? class Person { private String name="xia ...
- Linux的open函数的调用过程,Linux 中open系统调用实现原理
用户空间的函数在内核里面的入口函数是sys_open 通过grep open /usr/include/asm/unistd_64.h查找到的 #define __NR_open2 __SYSCALL ...
- 初始化栈、入栈、出栈、栈空、数制转换函数和主函数,实现1348转换成8进制的功能。
#include<stdio.h> //栈的顺序存储 #include<string.h> #include<stdlib.h> #include<mallo ...
最新文章
- 使用Donut Caching和Donut Hole Caching在ASP.NET MVC应用中缓存页面
- 一次哔哩哔哩面试经历,真香!
- 树莓派3b python3.6.1 SSL模块调用不起来的坑
- InstallShield 2015 生成单个EXE包和 MSI包
- TIBCO BusinessWorks 6和Container Edition与BW5的比较
- 将一个BYTE数组转换成16进制字符串和10进制字符串格式
- ++操作你还在使用加锁去保证线程的安全吗?确定不了解一下CAS机制?
- 讨一个上海中上条件的老婆的成本 (zz)
- 空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)
- 基于MATLAB视频的人体姿态检测
- matlab保存pgm图形,matlab读写pgm文件
- 如何查看电脑是否支持CUDA及支持的CUDA版本
- VS2008+VP5开发环境配置
- ie退出全屏快捷键_讲解win7电脑全屏快捷键介绍
- struts漏洞总结
- 深圳云计算培训:怎么进入云计算这个行业?
- 蓝牙连接便携式打印机(芝柯) uniapp
- advanced mathematics 8
- WebRTC 播放视频MP4
- HTML5版切水果游戏 HTML5游戏极品源码下载
热门文章
- Windows和Linux的C/C++ IDE选择
- 我看过的数据库方面的好文章
- linux中的网络配置
- win10系统英雄联盟老是重新连接服务器,win10lol重新连接无法连接服务器重试该怎么才能解决...
- linux tomcat 进程杀掉_Linux-(一)常用命令总结
- java简体(繁体)转换器
- Dapps-是一个跨平台的应用服务商店
- oracle 10g sqlplus登录显示问号,oracle sqlplus 连接时,connection to 显示的是问号
- java加减乘除运算代码_从“位运算”炫技到“操作符”,再到逐步理解“群论”...
- Java web 环境搭建-Linux