学生 邵帅《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 课程
这门课程学习的汇编是AT&T的汇编命令,从左到右看,堆栈里一开始栈基指针%ebp栈顶指针%esp都指向栈底,堆栈地址从上到下,地址从大到小。寄存器前面有个e代表它是32位的。
这是一个简单的c语言程序函数g的功能是返回参数x加10后的值,函数f返回函数加1后的值,main函数返回函数f参数11时加1后的值。
这是汇编后的代码,从图中可以看到第一列的f: g: main:分别代表各自名字的函数名,在他们之后的是函数实现的代码块。
首先分析第一个函数,pushl %ebp 作用是将栈顶指针%esp减4,然后将%ebp的地址给%esp的值。movl %esp, %ebp将esp寄存器和ebp寄存器指向同一个内存地址,movl 8(%ebp) %eax 将ebp加8并且放入eax,addl %10, %eax 将值10放入eax中累加。popl %ebp 将ebp所指的内容弹出堆栈。 ret 则是return其他两个函数大体相同- -,看看之前没有的代码,比如call g 调用g函数,leave使堆栈恢复之前的样子。
分析main函数,首先ebp压栈,将esp指向ebp相同的地址,esp减4,esp指向的地址所存的值为11,调用函数f,esp通过累加寄存器加1,然后恢复栈顶指针,将esp返回给eip。
总结:通过这个程序我知道了每一个函数都是对堆栈的寄存器操作,通过堆栈这个数据结构可以对局部变量的生命周期有很好的管理,main函数作为整个程序的入口,使用call来调用其他函数。每个程序都是通过main函数启动的,系统会把他作为起点。我对于汇编和计算机系统的学习还远远不够,有很多错误。
查了一下百度,了解到push和pop指令,例如指令push %eax是将 %eax中的值压入栈,即将%esp的指针向下移动4个字节(32位中地址减4),并且将%eax的值给%esp。指令pop %eax 将%esp的值出栈,赋值给%eax,即将%esp的值给%eax,并且%esp指向的地址加4(即向上移动4个字节)。