第一部分
程序代码:
通过如下指令
第二部分
生成main.s文件,即汇编代码
main.s文件汇编代码删掉部分无关代码,如下所示
g:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
addl $10,%eax
popl %ebp
ret
f:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
movl 8(%ebp),%eax
movl %eax,(%esp)
call g
leave
ret
main:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
movl $29,(%esp)
call f
addl $5,%eax
leave
ret
第三部分
汇编代码如上,分析采用图解,如下所有图零.
一.
二.
三.
四.
五.
六.
七.
八.
九.
十.
十一.
十二.
十三.
十四.
十五.
十六.
十七.
十八.
十九.
二十.
二十一.
图终于贴完了,二十几张图有点害怕。。。
以上每幅图解释了指令的执行,和esp等寄存器的指向及堆栈的变化
第四部分
总结:程序编译生成汇编代码,然后eax,esp,ebp,eip等寄存器结合堆栈实现汇编代码的执行,
由eip寄存器可以发现是不断的从内存中取出代码指令,然后CPU执行,通过esp记录当前堆栈的位置,
通过ebp记录当前函数的基地址,通过call指令实现函数之间的调用跳转,通过ret指令实现函数的返回等等。
所以综上,计算机的运行就是不断的取指令,执行指令的过程。
王宣原创作品转载请注明出处《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000