[CSAPP学习笔记] 栈帧

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

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函数因为没有对输入范围进行限制会导致很严重的后果,直到学习到这里才明白。正如上面所说,栈帧空间有一部分是用来保存过程中的局部变量。假如我们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值