Linux内核分析(一)
来源:互联网 发布:soa java 编辑:程序博客网 时间:2024/05/17 07:30
Linux内核分析 —— 【实验一:栈与程序 】
栈,是一种数据结构,是一种有限制的一维线性表。它的特点是“先进后出”,就像是一条只有一人宽的死胡同,先进胡同的人必须等后进胡同的人全部离开后,才能离开。
但栈与程序之间又有什么联系呢?
首先,看一段简单的C程序代码:test1.c
int g(int x) { return x + 2; } int f(int x) { return g(x); } int main(void) { return f(5) + 8; }
1) 在Linux 64位系统环境下,用以下命令将上述代码进行反汇编:
gcc –S –o test1.s test.c -m32
如下图如示
2)用gedit软件打开test1.s文件:
可以看到三个函数g,f,main对应的汇编代码,下面分析这个程序在栈中是如何执行的。
3)我们都知道main函数是程序的入口,所以先看main函数。注意:test1.s文件中以 ’ . ‘开头的都是编译器所添加的,可以忽略。
程序在内存中栈的增长方式如下:
每一个函数在调用的时候都会在内存中(也就是栈中)开辟一块属于自己的临时空间,称为一个栈帧,它用于存储该函数运行过程中的临时变量,在函数调用结束后就会清除。程序在执行main函数时,栈的变化为:
上图(1)中没有标示出ebp的位置,但我们知道它在更高的内存位置上。push ebp 就是把这个位置保存起来,以便于在修改ebp指针后,仍然可以恢复原来的值。
(2)中将当前esp位置赋给了ebp,也就是说栈底指针往下内存地址方向移了一段距离,和栈顶指针在同一位置。
(3)相当于push 5。5 是 f 函数的参数,c 程序函数参数的传递是通过栈来保存的。
(4)调用 f 函数。call f 可以看作是两条指令:push eip和jmp f 。把将要执行的指令地址ret1入栈,然后跳转到 f 函数,实现函数的调用。
(5)保存ebp1,把参数传给将要调用的函数g。
(6)调用函数g 。
(7)中绿色代表main函数的栈帧,蓝色是f函数的栈帧,黄色是g函数的栈帧。
(8)函数返回时,通常eax寄存器中的值作为返回值。语句”movl 8(%ebp),%eax” 和”addl $2 , %eax” 这表示将参数的值加2赋给eax,即eax=7。
(9)(10)中ret 相当于pop eip 。将栈中保存的返回地址赋给eip,使得可以正常返回到原来的调用者f中,而返回值保存在eax寄存器中。
(11)同理,f函数在执行后,将结果保存到eax返回到main函数。在f函数汇编代码中有一条“leave”语句,它相当于“mov ebp,esp”和”pop ebp”两条语句。
(12)在main函数中,语句”addl $8,%eax“则表示将f函数的返回值加上8,结果为eax=15 。再执行一次”leave“栈就被清空了。main函数也是函数,它也有它的调用者,只是我们看不到它的调用者而已,但它也需要”ret“返回到调用者,到这我们的程序就算结束了。
通过以上的例子,我们可以知道栈在程序执行过程中发挥着至关重要的作用,栈这种特殊的数据结构为函数的调用提供了可能,使得程序的执行更加灵活、过程更加直观;也使得编程更加简单、方便;同时,只有理解栈的结构和性质,才能理解程序是如何执行的。
=========== 王杰 原创作品转载请注明出处==============
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”
- 分析linux内核(一)
- Linux内核分析(一)
- Linux内核分析(一)
- Linux内核分析(一)
- Linux内核分析(一)
- 一、Linux内核分析
- linux内核分析--异步io(一)
- linux内核分析--异步io(一)
- Linux内核启动分析(一)
- linux内核分析:read过程(一)
- Linux内核启动应用程序分析(一)
- linux内核分析--内核中的数据结构之双链表(一)
- Linux内核分析:实验一
- Linux内核分析:实验一
- Linux内核分析实验一
- Linux内核分析:实验一
- Linux内核启动分析一
- Linux 2.6.28 – 内核启动分析(一)
- diamond配置中心部署
- type_traits之has_* 系列
- 微信URL设置问题
- hdu 1501 Zipper(DFS)
- Dubbo应用学习(1)
- Linux内核分析(一)
- NSURLConnection+ NSMutableURLRequest(iOS9)
- 精密测量常用方式
- spring框架获取原型对象
- android的类很多,需要经常查看这些API
- 有两个变量a和b,不用if等判断语句,求两者较大的值
- Linux netstat命令详解
- maven 命令
- Android逆向分析基础-Dalvik虚拟机