代码改变世界

Linux内核分析

2016-02-28 14:29  KG35  阅读(355)  评论(0编辑  收藏  举报

通过分析汇编代码理解计算机是如何工作的

 

网易云课堂《Linux内核分析》作业

实验目的:

通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

实验过程:

登陆实验楼虚拟机http://www.shiyanlou.com/courses/195

准备main.c源码

main.c

打开终端shell,输入以下命令:

gcc –S –o main.s main.c -m32

生成汇编代码main.s

main.s.part1
main.s.part2
main.s.part3

精简后的汇编代码

main.s

实验分析:

先看C语言代码,该程序由3个函数组成,分别是main()、f()、g(),实现了2+7+5的简单数学计算。

程序首先从main()开始,将数字2传入f(),f()又将main()传入的数字2原封不动的传给g(),g()实现了将传入2加5的操作,结果7返回给f(),f()获得7后直接返回给main(),mian()将获得的7加7后返回最终结果14.

理论上编译后的汇编语言也应该实现上述功能,即计算2+5+7值。

下面我们来分析精简后的汇编代码:

左边代码行标表示eip,红框表示当前运行的代码,eax初始化为未知变量,右边蓝色格子表示内存段,为简化描述在32位环境下1个内存单元格表示4byte,ebp和esp初始值均为0

程序从main开始

1

将ebp压栈,相当于执行以下两条语句:

subl $4, %esp //esp减4byte,向下移动1格,此时esp指向1

movl %ebp, (%esp) //将ebp的值存入esp指向的存储单元内

2

将esp的值赋值给ebp,即ebp也指向1

3

将esp的值减4,即esp向下移动1格,此时esp指向2

4

将数字2存入esp指向的内存块

5

调用f,相当于执行以下两条语句:

pushl %eip

move f, %eip

6

call f执行完后的状态,此时程序完成由main跳转到f

7
8
9
10

该条指令将ebp-8的位置,即标号为2的内存单元所存放的数字2赋值给eax,此时eax等于2

11
12

跳转到g

13
14
15
16
17

将eax的值加5后再存入eax,此时eax等于7

18

出栈操作,相当于以下两条语句:

movl (%esp), %ebp

addl $4, %esp

19

ret相当于执行以下语句:

popl %eip

20

leave相当于执行以下两条语句:

movl %ebp, %esp

popl %ebp

g没有leave指令语句的原因是它没有再调用其他函数

21
22
23

将数字7累加到eax,此时eax等于14

24
25
26

至此整个程序完成了所有操作,结果存放在eax,即14为最终计算结果,与C语言代码一致。

实验总结:

计算机有一套规则来控制程序运行,在C语言和汇编语言中,CPU从程序main函数所在的内存地址开始做取指操作,根据当前状态和输入计算出新值,并且进入一个新的状态,同时改变寄存器所存储的数值。

参考:计算机实际上是如何工作的