通过反汇编理解计算机程序执行过程
来源:互联网 发布:百年孤独中的名句 知乎 编辑:程序博客网 时间:2024/05/23 00:03
李宗峰 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
本文探究下面一段代码的工作原理:
1. int g(int x)
2. {
3. return x + 3;
4. }
5.
6. int f(int x)
7. {
8. return g(x);
9. }
10.
11. int main(void)
12. {
13. return f(8) + 1;
14. }
此处进行试验的环境是在virtualbox虚拟机上创建一个linux虚拟机,虚拟机为32位。Virtualbox版本:
linux虚拟机安装的系统版本:
下面开始进行试验,首先新建一个目录专门用于此次的实验,然后新建test.c文件,将上面的代码复制到test.c中,直接在宿主机和虚拟机之间进行复制的话需要安装virtualbox增强工具由于代码比较短,可以直接敲代码进去就好了。
然后将源文件编译成汇编代码,命令如下:gcc –S –o test.s test.c -m32
然后打开test.s如下图所示:
汇编代码中的以.开头的部分是不会执行的,只是用来对代码进行标记的。为此我们删除所有的无关行,得到精简的版本如下所示:
可以看到上面的代码跟我们的c程序源代码是对应的。
我们做这个实验的目的是了解计算机的工作过程,我们现在计算机是冯诺依曼体系的,这个体系概括起来就是程序存储执行,程序每次执行的代码存放在寄存去eip指向的地址,每次程序执行eip指向的指令然后将eip的值加“1”,指向下一条指令。由于每一条指令的长度可能不一样长,所以这里的“1”是一条指令。
像是eip为指向当前cpu要执行的指令一样,CPU(这里为80386)上的寄存器一般都有自己的用途,具体用途如下:
1. 通用寄存器(EAX、EBX、ECX、EDX、ESP、EBP、ESI、EDI)
2. 段寄存器(CS、SS、DS、ES、FS、GS)
3. 指令指针寄存器和标志寄存器(EIP、EFLAGS)
4. 系统表寄存器(GDTR、IDTR、LDTR、TR)
5. 控制寄存器(CR0、CR1、CR2、CR3、CR4)
6. 调试寄存器(DR0、DR1、DR2、DR3、DR4、DR5、DR6、DR7)
7. 测试寄存器(TR6、TR7)
具体的寄存器使用等介绍可以求助谷歌大神。
下面分析汇编代码的执行过程:
首先函数从main函数开始执行,可以看到main、f、g函数开始都是
pushl %ebp
movl %esp %ebp
这两行汇编代码,这两段代码的功能就是将当前的栈底保存,然后将栈底指向当前的栈顶,这样的话可以起到保存程序执行到此时的现场,便于函数执行完之后恢复现场。每个函数执行完之后最后的leave指令是这两个指令的逆执行:
movl %esp,%ebp
popl %ebp
每个函数leave之前到开始的第三行为程序的实际执行代码。
下面逐行分析汇编指令:
Subl $4,%esp 将栈顶减四
Movl $8,(%esp)将8存到栈中。
Call f 调用f函数
然后进入f函数分析,首先保存现场然后从第三行开始正式执行函数的任务:
Subl $4 %esp 将栈顶上移一位
Movl 8(%ebp) %eax这里8(%ebp)指向的是main函数中存放数字8的位置(在栈中放入8之后又一次压栈操作和将栈顶上移操作,两次操作使栈顶上移了8位).这一步将8放入eax中。
Movl %eax (%esp) 将eax中的值放入栈顶。
Call g 调用函数g
Movl 8(%ebp),%eax 分析压栈情况可以知道此时是将8放入eax中。
Addl $3, %eax将eax中的数值(8)加3,并返回(一般使用eax存放返回值)。
最后由于是一直返回,所以此处使用popl %ebp既可以完成弹栈操作。
从这段实验可以看出,计算机的执行过程为:eip始终指向当前执行的指令,每个函数执行的时候都有相对独立的堆栈,参数都是通过堆栈进行传递。
- 通过反汇编理解计算机程序执行过程
- 通过分析一个C程序的汇编指令执行过程,理解计算机的工作。
- 通过反汇编程序观察计算机执行过程
- 通过反汇编程序观察计算机执行过程
- x86平台 通过反汇编简单的从程序,分析理解计算机是如何工作的。
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(原创)
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- linux下反汇编一个程序,并通过分析汇编代码理解计算机是如何工作的
- 通过反汇编代码探究计算机运行过程
- 通过反汇编代码探究计算机运行过程
- 云课堂 Linux内核分析 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 云课堂-linux内核分析:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- Linu内核分析一 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- Linux内核分析课程--通过反汇编一个简单的c程序,分析汇编代码并理解计算机如何工作的
- 反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- jquery mobile带表单参数的changePage
- SQL语句大全
- 【高效算法设计】UVa120 Stack of Flapjacks
- 发送HTTP请求的方法:GET & POST
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)
- 通过反汇编理解计算机程序执行过程
- Linux下的tar压缩解压缩命令详解
- 二进制,八进制,十进制,十六进制之间的转换.以及二进制转十进制8421
- zoj 3229 Shoot the Bullet(有源汇有上下界的最大流)
- Socket网络开发入门
- PostgreSQL 获取含有某字段的 table
- robotium clickonscreen()出现INJECT_EVENT permission的临时解决方案
- Json 数据解析& JSONKID框架
- PostgreSQL获取table名,字段名