来源:

1、《代码揭秘》第六章函数与函数调用

2、http://blog.csdn.net/zhuliting/article/details/6839233


引入话题:

局部变量是动态分配的-》降低了运行效率-》为了使得动态分配的代价最小化,编译器试着每次为一大组局部变量分配空间,而不是每次为单独的一个变量分配空间

-》对于函数来说,被分配给每次函数调用的那一大块内存叫作“活动记录”  (”活动记录“在函数调用时被创建,当函数返回时被销毁)


”活动记录“存放在栈中,栈指针和帧指针界定了活动记录的范围。其中栈指针始终指向栈顶,帧指针为一个活动记录的开始地址。

在汇编语言中,帧指针存放在EBP寄存器中,栈指针存放在ESP寄存器中。

参考:http://www.cnblogs.com/shitouer/archive/2010/04/05/1704554.html

#include <stdio.h>

int sum(int a,int b,int m,int n)
{
return a+b;
} int main()
{
int result = sum(1,2,3,4);
}

 使用反汇编技术分析上述代码见上述参考博客。下面主要是根据反汇编结果给出的栈图

 

一般进入函数后,要完成3步:

1、旧的帧指针入栈

2、EBP = ESP;

3、栈指针减小

阴影部分为main函数开始时的ESP和EBP。进入main函数后,首先,旧的帧指针入栈(旧的EBP为0x0012FF88),因为指针占4个字节,所以ESP由原来的

0x0012FF4c变为0x0012FF48.

接着push ebx push esi  push edi

以及lea edi, [ebp-44h]

接着程序运行到 int result = sum(1,2,3,4);

即:进入函数sum(....)中,此时”活动记录“变为函数sum的活动记录。

4个参数入栈,栈中情况变为如下图所示。

接着,保存返回地址(在我做的实验中,返回地址为0x00401085)

接着将旧的EBP入栈,保存起来,这个旧的帧指针是main函数活动记录的帧指针:0x0012FF48

然后将EBP=ESP

接着sum函数的活动记录的ESP减小

int sum(int a,int b,int m,int n)
{
 return a+b;
}

在sum函数中,如何找到a+b,即1+2;

由上图可见,EBP+8所在的位置为1,EBP+12所在的位置为2.

下篇图解函数函数返回时的问题。

c语言活动记录-图解(一)的更多相关文章

  1. C语言过程活动记录

    C 语言自动提供的服务之一就是跟踪调用链——哪些函数调用了哪些函数,当下一个return语句执行后,控制将返回何处等.解决这个问题的经典机制是堆栈中的活动记录. 当每个函数被调用时,都会产生一个过程记 ...

  2. .NET应用架构设计—适当使用活动记录模式代替领域模型模式

    阅读目录: 1.背景介绍 2.简单介绍领域模型模式.活动记录模式 3.活动记录模式的简单示例及要点 4.总结 1.背景介绍 对软件开发方法论有兴趣的博友应该发现最近“领域驱动设计”慢慢的被人发现被人实 ...

  3. 函数调用堆栈及活动记录 堆栈溢出 stack overflow

    小结: 1.当被调函数返回主调函数时,被调函数的 活动记录-activation record / 堆栈帧-stack frame 被 弹出-popping 程序执行栈-program executi ...

  4. 架构模式数据源模式之:表数据入口(Table Data Gateway)、行数据入口(Row Data Gateway)、活动记录(Active Record)

    一:表数据入口(Table Data Gateway) 表数据入口提供了用于访问单个表或者视图(也包含了联表查询)的所有SQL,通常一个表一个类.其它代码通过它来实现对数据库的交互.基于这个特点,表数 ...

  5. yii学习笔记(6),连接数据库,创建活动记录类

    创建数据库用于测试 配置数据库连接 打开yii的配置文件目录下的数据库配置文件config/db.php <?php return [ 'class' => 'yii\db\Connect ...

  6. SpringBoot与MybatisPlus整合之活动记录(十五)

    活动记录和正常的CRUD效果是一样的,此处只当一个拓展,了解即可 pom.xml <dependencies> <dependency> <groupId>org. ...

  7. C语言(记录)——内存相关_2:内存的编址与管理

    本文是基于嵌入式的C语言 --------------------------------------------------------------------------------------- ...

  8. C语言学习记录_2019.02.10

    sizeof:给出某个类型或某个变量在内存中占据的字节数:(1个字节8位,即8比特) 格式符 (1)%ld表示数据按十进制有符号长型整数输入或输出. (2)%d表示数据按十进制有符号整型数输入或输出. ...

  9. 在Go语言中记录log:seelog包

    前两周调bug调的吐血,虽然解决了但是还是挺浪费时间的.跟同事聊了聊,觉得我们现在项目中的日志记录太少了,导致出了问题不知道怎么下手,还得自己改代码记录日志,然后排查问题.这样如果将来还有bug的话还 ...

随机推荐

  1. ubuntu14.04搭建Hadoop2.9.0伪分布式环境

    本文主要参考 给力星的博文——Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04 一些准备工作的基本步骤和步骤具体说明本文不再列出,文章中提到的“见参考”均指以上 ...

  2. hdu4348区间更新的主席树+标记永久化

    http://acm.hdu.edu.cn/showproblem.php?pid=4348 sb的标记永久化即可,刚开始add和sum没复制过来wa了两发...,操作和原来的都一样,出来单点变成区间 ...

  3. 如何用Tomcat部署前端静态文件

    在项目开发的过程中,一些公司经常是前后台分开的,并不是所有的前端文件都在后台项目中,尤其是互联网公司.这时候就需要后端人员单独运行前端文件.怎么用Tomcat部署运行前端静态文件呢? 工具/原料   ...

  4. react-router-dom: 重定向默认路由

    <appLayout> <Switch> <Route path='/' exact render={()=> ( <Redirect to={this.ge ...

  5. sql server显示行号

    --    工具-> --    选项-> --    文本编辑器-> --    所有语言-> --    常规-> --    显示-> --    行号

  6. PostgreSQL 日常SQL记录

    平时用的比较多的SQL语句,有时候会忘掉一点点,在这里记录一下: 1.创建表的同时,插入数据: create table test as select generate_series(1, 10000 ...

  7. C++中关于标准输出流cout中使用递增运算符的问题

    今天听同学提起一个问题,在C++中运行下面的语句会得到什么结果: ; cout << a++ << a++ << a++; 起初我个人想当然地认为会输出012,然而 ...

  8. NGINX 配置文件配置url重写

    1.项目在根目录: location / {            index  index.html index.htm index.php l.php;            autoindex  ...

  9. Gatling:开源压力测试框架之入门

    Gatling是一款开源的压力测试工具,基于Scala, Akka and Netty. 可录制测试脚本,也可以手动编写脚本,适合有编程经验的测试人员使用: 支持测试用例的参数化,可以使用csv.js ...

  10. 【Javascrpt 速成篇】 一:js基础

     本系列文章Javascript一律简称js,javascript太长了((⊙﹏⊙)b) js概述 js是面向对象和基于事件驱动的解释型语言,主要用于WEB前端,处理用户交互.几年前js只是作为一种前 ...