本周学习了Linux内核分析第一课,老师通过讲解一个简单的c程序使我了解了计算机(特别是堆栈部分)工作过程。
下面通过一个简单的例子来分析一下:
下面是c程序:
int g(int x) { return x + 6; } int f(int x) { return g(x); } int main(void) { return f(5) + 2; }
使用下面命令反汇编c程序得到汇编程序
gcc –S –o main.s main.c -m32
首先从main函数开始分析,可以发现每个函数中前两步都是将原来的ebp值压栈,并将ebp与esp对齐以为一段新的函数准备堆栈空间。
然后main中将数字5存入了esp中,再调用函数f,call f时会将eip值(call的下一条指令地址)压入栈中。
跳到f函数后也是先将ebp压栈,并对其ebp esp。而后将ebp地址加8的内存空间中的值(ebp指向4 也就是将2中的值5)传给eax.以上其实就是完成了从main函数中将参数5传给
函数f,然后参数5也被存入栈中。继而调用函数g。
g的前3步也是完成了将ebp压栈 ,对齐,将参数传给eax等操作。而后则执行g函数将x+6.至此上面堆栈的左部分分析完毕。
下面执行pop %ebp弹出ebp然后再ret 则让ebp esp恢复成了call g之前的状态,同时eip则指向了第15行也就是leave,
leave起到的作用是将ebp ,esp之间的堆栈空间清除,而后再pop ebp ,ret则跟上面一样,这俩步完成后esp ebp又回到了调用f之前的状态。
程序返回到main中的第23行继续执行。
从上面简单的分析我们可以看出。当我们的计算机运行程序时,程序与数据存储在内存空间之中,计算机根据ip中值按序执行程序。而同时内存中开辟堆栈空间存储各种数据,通过几个常用寄存器的协同工作,数据在内存空间与寄存器中传递来实现数据的运算与存储。同时ip值存储在堆栈中的概念,则让程序可以非顺序的执行。
这种存储程序计算机的运行方式使我们的cpu和内存协同工作,内存存储数据和指令,cpu则进行解析、运算。这样将程序和运算有机的结合在了一起,让现代计算机得以高效的运行。
陈浩 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000