什么是堆栈帧

可以肯定地说,任何设计合理的程序都是围绕着数据进行设计的。哪些数据必须由程序来管理呢?在程序中这些数据最准确、高效的表示方法是什么?这些都是有经验的软件设计人员和软件开发人员必须知道的最基本的问题。
对逆向工程而言,数据也是同样重要的。要真正理解一个程序,逆向者必须理解这个程序的数据。只要理解了程序中关键数据结构的总体规划和设计目的,我们就可以相对比较轻松地破译我们感兴趣的特定的代码区域。
本附录讲解了各种各样与程序中底层数据管理相关的主题。我们将从堆栈开始,讨论在程序中是如何使用堆栈的,然后接着讨论程序中使用的几种最基本的数据构造(data constructs。译注:数据构造要比数据结构的含义更广泛。),比如说变量,等等。接下来一节我们讨论数据在内存中的布置,并且描述了(从底层代码的视角来看)数组、链表等常用的数据构造。最后,我将演示类在底层是怎样实现的以及怎样在逆向工程中识别类。

C.1 堆栈

可以说堆栈是一块连续的内存,在系统中运行的例程将它组织成“层状”结构。堆栈中的内存单元在函数的生命周期内可以使用,而当函数返回时,这些内存单元就会被释放(释放后其他函数就可以用了)。
接下来的几小节将展示堆栈是怎样组织的,并讲述各种决定堆栈的基本布局的调用约定。

C.1.1 堆栈帧

堆栈帧指的是在堆栈中为当前正在运行的函数分配的区域(或空间)。传入的参数、返回地址(当这个函数结束后必须跳转到该返回地址。译注:即主调函数的断点处)以及函数所用的内部存储单元(即函数存储在堆栈上的局部变量)都在堆栈帧中。
对函数来说,堆栈帧内部具体的布局是一个非常关键的问题,因为布局会影响到函数访问堆栈中存放的传入参数以及存放其内部数据(例如局部变量)的方式。大多数函数调用代码都是以一段为函数设置堆栈帧的序言(prologue)开始的。设置堆栈帧的目的是:通过将一个指针存放在堆栈中参数区域和局部变量区域之间的那个单元,使得函数可以简便而快捷地访问这些参数和局部变量。这个指针通常存放在一个辅助寄存器中(通常是EBP),而腾出来ESP(ESP是主堆栈指针)来记录当前堆栈位置(即堆栈顶)。当前堆栈位置非常重要,因为这个函数可能还需要调用另外一个函数——这种情况下在ESP指向的当前位置下面(译注:“下面”指的是更低内存地址,而不是图C.1中所示的那种“上下”关系)的区域就要被用来给被调函数创建一个新的堆栈帧了。
图C.1展示了堆栈的总体布局以及堆栈帧是怎样布置的。


什么是堆栈帧_第1张图片
144434732.jpg

总结:
堆栈帧是一个为函数保留的区域,用来存储关于参数、局部变量和返回地址的信息。
堆栈帧通常是在新的函数调用的时候创建,并在函数返回的时候销毁。
说白了,堆栈由堆栈帧组成. 当调用函数时堆栈帧被压入栈中, 当函数返回时堆栈帧被从栈中弹出. 堆栈帧包括函数的参数, 函数地局部变量, 以及恢复前一个堆栈帧所需要的数据。

你可能感兴趣的:(什么是堆栈帧)