CSAPP第三章的重点在我看来就集中在对栈帧的理解上了。IA32过程调用就是通过各种栈帧来实现的。
栈帧(Stack Frame):为单个过程(Procedure)分配的那部分栈。
因此栈帧存在于栈上,每个过程又各自拥有自己独自的栈帧。栈帧以两个指针定界:栈指针%esp寄存器和帧指针%ebp寄存器,%esp在执行时需要不停移动,因此信息一般是靠单个过程中固定不变的帧指针%ebp来访问。下图是一个典型的栈帧结构(注意栈结构是地址向下增长的):

假设调用帧(Caller’sframe)为过程P的栈帧结构,而当前帧(Currentframe)为所调用的过程Q的栈帧结构。
由图中可以看出,在调用Q之前,P要把传递给过程Q的参数Argument1到Argument n按照地址增长的顺序存放(注意此时帧指针%esp指向Argument1)。
一旦执行call 指令调用过程Q,返回地址会被立即压入栈中(注意push指令会将减少%esp的值)。
而在开始执行Q过程前,要把P的帧指针%ebp保存起来(这样从Q返回之后才能找到P栈帧的位置),然后把%esp栈指针赋值给%ebp,让帧指针%ebp指向这个新栈帧的帧底,接着减小栈指针%esp的值使其指向新栈帧的帧顶,过程Q的栈帧空间也就分配好了。
这些空间还可以用来保存Q过程中一些局部变量(这一点需要注意,后面会进行扩展),被调用者保存的寄存器(Callee_saved Registers),以及(假如Q过程还要调用其他过程)新调用过程所需要的一些参数。
以前我一直不理解栈溢出带来的危害,不懂为什么gets函数因为没有对输入范围进行限制会导致很严重的后果,直到学习到这里才明白。正如上面所说,栈帧空间有一部分是用来保存过程中的局部变量。假如我们

本文介绍了CSAPP中关于栈帧的概念,特别是IA32过程调用如何利用栈帧进行参数传递和局部变量存储。栈帧由栈指针%esp和帧指针%ebp定义,栈溢出的危害在于它可以覆盖帧指针和返回地址,导致程序混乱。在x86-64架构中,栈帧不再需要帧指针,信息访问依赖于%rsp,且有一个Red Zone供过程使用。

5749

被折叠的 条评论
为什么被折叠?



