过程调用与栈帧
来源:互联网 发布:远光软件工资待遇 编辑:程序博客网 时间:2024/06/05 18:07
本博客(http://blog.csdn.net/livelylittlefish)贴出作者(三二一@小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!
过程调用和栈帧
1. 过程调用
一个过程调用包括将数据和控制从代码的一部分传递到另一部分。
过程调用的任务:为过程的局部变量分配空间,并在退出时释放这些空间,俗称保存现场/恢复现场。
2. 栈帧
栈的作用:参数传递、局部变量分配、保存调用的返回地址、保存寄存器以供恢复
IA32程序用程序栈来支持过程调用。
栈帧:为单个过程分配的那部分栈称为栈帧(stack frame)
下图表述了一个通用的栈帧:
high address |=================|<----+
| | |
| | |
| | |
| | previous stack frame
| | |
| | |
| | |
|=================|<----+
| ... | |
| | |
|-----------------| |
4+4n | param n | |
|-----------------| |
| ... | caller stack frame
| | |
|-----------------| |
+8 | param 1 | |
|-----------------| |
+4 | return addr | |
|=================|<----+
%ebp-> | %ebp' | | //this saved %ebp' for previous stack frame
|-----------------| |
| | |
| saved register | |
| local variable | |
| temp variable | |
|-----------------| |
| | callee stack frame
| param section | |
| | |
|-----------------| |
| | |
|-----------------| |
%esp-> | | |
low address |-----------------|<----+
帧指针:%ebp,指向栈底,在本过程中,%ebp值保持不变
栈指针:%esp,指向栈顶,程序执行时,栈指针可以移动,来分配或释放空间
- %esp减小——分配空间
- %esp增大——释放空间
因%ebp不变,而%esp可变,故程序执行中,大多数信息的访问都是相对于帧指针的,例如如下指令:
lea 0xffffffe8(%ebp), %eax ;将%ebp-24地址中的数据(实际上是地址)存入%eax寄存器
(回忆一下《汇编语言》,lea是什么?。。。。lea:Load Effective Address)
(为什么是%ebp-24?。。。。因为计算机中数据是用反码表示的,反码0xffffffe8表示的值即为-24,即-0x18)
考虑这样一个调用,调用者caller,被调用者callee。
当caller调用callee时,caller的返回地址被压入栈中,形成caller栈帧的末尾。
返回地址:就是当程序从callee返回时应该继续执行的地方(指令的地址),当被调用过程返回时,程序会从此处继续执行。
callee的栈帧从保存的帧指针的值(%ebp)开始,其后即为其保存的寄存器的值,和callee调用其他过程的参数。
思考:为什么(非寄存器)局部变量存放在栈中而非寄存器中?
- 寄存器不够存放所有的局部变量
- 有些局部变量是数组或结构,必须通过数组或结构引用来访问
- 若要对一个局部变量使用地址操作符“&”,必须能为它产生一个地址
一般地,C/C++程序的调用方式为__cdecl,即参数从右向左的顺序入栈;如此,则%ebp+0x8为第一个参数,%ebp+0xc为第二个参数,以此类推。(默认地,编译器会考虑内存按双字对齐)
3. 各类型的数据在栈中的排列方式
栈的增长方式:由高地址向低地址方向增长
数据存放方式:
例如内存中存放的long型数据为0x12345678
a. 高端法(Gig Endian)
高字节(高位) => 低地址
低字节(低位) => 高地址
|----------|
0x2003 | 78 | high address
|----------|
0x2002 | 56 |
|----------|
0x2001 | 34 |
|----------|
0x2000 | 12 | low address
|----------|
数组存放方式(大端法):
例如int a[8];
|----------|
a[7], 0x2017 | 80 | high address
|----------|
a[6], 0x2016 | 70 |
|----------|
a[5], 0x2015 | 60 |
|----------|
a[4], 0x2014 | 50 |
|----------|
a[3], 0x2013 | 40 |
|----------|
a[2], 0x2012 | 30 |
|----------|
a[1], 0x2011 | 20 |
|----------|
a[0], 0x2010 | 10 | low address
|----------|
b. 小端法(Little Endian)
高字节(高位) => 高地址
低字节(低位) => 低地址
|----------|
0x2003 | 12 | high address
|----------|
0x2002 | 34 |
|----------|
0x2001 | 56 |
|----------|
0x2000 | 78 | low address
|----------|
4. 过程调用和返回指令
- call : 过程调用,有一个目标地址(被调用过程起始点指令地址)
任务:将返回地址入栈,并跳转到被调用过程的起始处
- leave:为返回准备栈
任务:
movl %ebp, %esp ;set stack pointer to the beginning of frame
popl %ebp ; restore saved %ebp and set stack ptr to the end of caller's frame
- ret : 从过程调用中返回
任务:从栈中弹出返回地址,并跳转到那个位置
%eax通常用来返回值,如果函数要返回整数或指针。
Reference
关于程序调用方式:
http://yangwei.blogbus.com/logs/1550582.html
http://blog.csdn.net/cradmin/archive/2008/10/22/3124159.aspx
栈帧结构:
《深入理解计算机系统》
http://bigwhite.blogbus.com/logs/2005/11/1592114.html
http://bbs.tech.ccidnet.com/read.php?tid=645517
- 过程调用与栈帧
- 栈帧与函数调用过程分析
- 栈帧与函数调用过程
- 编译过程与调用栈
- 堆栈、栈帧与函数调用过程分析
- 堆栈、栈帧与函数调用过程分析
- 堆栈、栈帧与函数调用过程分析
- 堆栈、栈帧与函数调用过程分析
- 堆栈、栈帧与函数调用过程分析
- 堆栈、栈帧与函数调用过程分析
- 栈帧与函数调用过程的分析
- 函数的调用过程,栈帧的创建与销毁
- 系统调用与过程调用
- 存储过程与Java调用
- 【应聘笔记系列】堆栈、栈帧与函数调用过程分析
- 函数调用过程(栈桢的形成与释放)
- 系统调用的初始化过程与系统调用执行过程
- 函数调用过程栈帧变化详解
- md5 slat vbb crack
- javascript拼图游戏
- C++ 变长数组,不定长数组
- 大学计算机课程复习--数据库原理
- 我好迷茫
- 过程调用与栈帧
- SQL语句---创建表
- Windows下搭建Subversion 服务器
- GNU/Linux编程指南
- 面试小技巧:三分钟让面试官眼前一亮
- verilog HDL数字钟Quartus工程
- 程序员职业规划发展路线图(综合才能型)
- daim
- 求《信号发生器功能程序设计》的程序!!!