通过分析汇编代码理解计算机是如何工作的
网易云课堂《Linux内核分析》作业
实验目的:
通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
实验过程:
登陆实验楼虚拟机http://www.shiyanlou.com/courses/195
准备main.c源码
打开终端shell,输入以下命令:
gcc –S –o main.s main.c -m32
生成汇编代码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开始
将ebp压栈,相当于执行以下两条语句:
subl $4, %esp //esp减4byte,向下移动1格,此时esp指向1
movl %ebp, (%esp) //将ebp的值存入esp指向的存储单元内
将esp的值赋值给ebp,即ebp也指向1
将esp的值减4,即esp向下移动1格,此时esp指向2
将数字2存入esp指向的内存块
调用f,相当于执行以下两条语句:
pushl %eip
move f, %eip
call f执行完后的状态,此时程序完成由main跳转到f
该条指令将ebp-8的位置,即标号为2的内存单元所存放的数字2赋值给eax,此时eax等于2
跳转到g
将eax的值加5后再存入eax,此时eax等于7
出栈操作,相当于以下两条语句:
movl (%esp), %ebp
addl $4, %esp
ret相当于执行以下语句:
popl %eip
leave相当于执行以下两条语句:
movl %ebp, %esp
popl %ebp
g没有leave指令语句的原因是它没有再调用其他函数
将数字7累加到eax,此时eax等于14
至此整个程序完成了所有操作,结果存放在eax,即14为最终计算结果,与C语言代码一致。
实验总结:
计算机有一套规则来控制程序运行,在C语言和汇编语言中,CPU从程序main函数所在的内存地址开始做取指操作,根据当前状态和输入计算出新值,并且进入一个新的状态,同时改变寄存器所存储的数值。
参考:计算机实际上是如何工作的