• c语言活动记录-图解(一)



    来源:

    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.

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

  • 相关阅读:
    BFS 简单思想以及代码
    01、Hibernate安装配置
    WireShark——ARP 协议包分析
    eNSP之VLAN设计实验
    eNSP 交换机 路由器 PC 互连设计/实现
    Windows常用的网络命令
    01、Git安装教程(windows)
    Java IO编程——文件拷贝
    Java 多线程编程——多线程
    Java IO编程——转换流
  • 原文地址:https://www.cnblogs.com/welsh-android-learning/p/3490863.html
Copyright © 2020-2023  润新知