通过反汇编一个简单的C程序,分析汇编代码,理解计算机是如何工作的
朱明涛 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
题目要求:
实验:
登录实验楼Linux64位实验环境,在Code文件目录下新建C语言.c文件(在Code目录下创建是为了方便代码下载到本地)
main.c内容如图
为了防止雷同,我们这里把样例中的部分代码进行了改动。
通过编译命令gcc -S -o main.s main .c -m32 我们得到文件main.s,它包含一个汇编语言程序,汇编语言程序中的每条语句都以一种标准的文本格式确切地描述了一条低级机器语言指令。这里需要注意的是命令中S要大写,使用-m32是因为实验楼提供的是64位的实验环境,而我们模拟的是X86结构,需要使用-m32转换成32位的
main.s内容如图
其中带有.号的代码语句指的是链接文件,与我们要讨论的内容关系不大,这里我们把带有.的语句删去,得到下面如图所示文件
分析:
程序从main函数开始执行,初始的堆栈为空,esp和ebp指向同一个地址。eip存放pushl %ebp(18)
执行18:pushl %ebp 保存老的ebp地址,把老的ebp地址压入堆栈,记为ebp0。eip存放movl %esp,%ebp(19)
执行19:movl %esp,%ebp 将esp的值放入ebp中,此时esp和ebp指向同一地址。eip存放subl $4,%esp(20)
执行20:subl $4, %esp 将esp的值减去4。eip存放movl $6,(%esp) (21)
执行21:movl $6,(%esp) 将立即数6放入esp所指向的地址中.eip存放call f(22)
执行22:call f将eip0(23)压入栈中,然后跳转到函数f:处执行。eip存放pushl %ebp(9)
执行9:pushl %ebp 将ebp1压入栈中。Eip存放movl %esp,%ebp(10)
执行10:movl %esp,%ebp 将esp的地址赋给ebp。Eip存放subl $4,%esp(11)
执行11:subl $4,%esp 将esp的值减去4。Eip存放movl 8(%ebp),%eax(12)
执行12:movl 8(%ebp),%eax 将ebp + 8所存放的值,放入eax寄存器中,ebp+8存放的值为6,所以此时eax寄存器存放的值为6.eip存放movl %eax,(%esp) (13)
执行13:movl %eax,(%esp) 将eax寄存器存放的值,放入esp所指向的地址中。Eip存放call g(14)
执行14:call g 将eip(15)压入堆栈,跳转到函数g:处执行。Eip存放pushl %ebp(2)
执行2:pushl %ebp 将ebp2压入堆栈。Eip存放movl %esp,%ebp(3)
执行3:movl %esp,%ebp 将esp的地址放入ebp中。Eip存放movl 8(%ebp),%eax (4)
执行4:movl 8(%ebp),%eax 将ebp + 8所指向的内容放入eax寄存器中,ebp + 8存放的内容为6,所以eax寄存器存放的内容为6。Eip存放addl $5,%eax (5)
执行5:addl $5,%eax 将eax寄存器的内容与5相加,将结果放入eax寄存器中, 此时eax寄存器内的值为11。Eip存放popl %ebp(6)
执行6:popl %ebp 将栈顶元素弹出,ebp指向ebp1。Eip存放ret(7)
执行7:ret Eip存放leave(15)
执行15:leave 相当于movl %ebp, %esp popl %ebp 将ebp寄存器的值放入esp寄存器中,弹出栈顶元素,存放到ebp中。Eip存放ret(16)
执行16:ret eip存放addl $2,%eax (23)
执行23:addl $2,%eax 将eax寄存器的值加上2,将结果放入eax寄存器中。Eip存放leave(24)
执行24:leave相当于movl %ebp, %esp popl %ebp此时堆栈回到初始状态。Eip存放ret(25)
执行25:ret 程序退出。Eip存放原先最早的值。
计算机是如何工作的:
通过反汇编这个C程序,可以看出计算机的执行过程,就是CPU读取一条一条的指令来进行执行,指令寄存器EIP指向下一条需要执行的指令。
程序执行过程中一些数据的保存,大都是通过堆栈进行的。堆栈寄存器EBP和ESP共同确定了一个堆栈的栈底和栈顶。
如有不当,欢迎指正交流
朱明涛 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000