原c语言代码如下:

int g(int x)
{
  return x + 15;
}

int f(int x)
{
  return g(x);
}

int main(void)
{
  return f(10) + 1;
}
copy

实验楼截图如下 实验楼

首先代码从main函数开始执行。 首先通过第一个压栈操作,把栈的基地址压倒内存中,比如此时的基地址是2000,那么esp地址减去4,地址为1996,里面存的内容为2000。 后面两个操作是让ebp指向esp(地址1996),然后再让esp地址减4,也就是esp地址为1992。 然后调用f函数,在内存中存下eip=23(也就是存入call f这个指令的下一个条指令),此时esp地址为1988

在函数f中,先把这个时候基地址1996压入栈中,esp为1984;移动edp指向esp的位置1984;执行第11行指令,esp地址为1980;执行第12行指令,寄存器eax的值为变址操作ebp地址1988+8=1996处的值10,即eax值为10。执行第13行代码,把eax的值赋值给esp所在位置的内存,即1980处的地址为10。此刻调用g函数,esp减4位1976,并让此地址存eip=15。

在g函数中,如同前面f类似,让存ebp地址,移动esp,变址ebp赋值15+10给eax,此刻ebp地址为1972,esp地址为1972。执行第6行代码,把esp中的1984赋给ebp,esp+4为1976。执行第7行代码ret,弹出eip=15,esp+4为1980。执行第15行代码,esp指向ebp为1984,并把1996弹出给ebp,esp+4=1988。执行第16行代码,eip=23,esp+4=1992。eax+1=>eax=26。执行第24行代码,esp指向ebp的1996,弹出2000使得ebp=2000。执行第25行代码,弹出2000存的eip给上一级,然后esp+4=2000。代码执行完毕。

从以上例子,我认为多任务执行和单任务类似,都是在内存中压栈,然后弹出,可能通过一些id来区分eip之类的,来保证多任务执行不会相互干扰。

作者:王磊+原创+linux内核分析()

最新评论
暂无评论~