函数调用过程初探

From:http://www.cnblogs.com/strugglever/

调用函数的代码

  1.调用函数的逻辑代码

  2.函数调用代码

    a.将参数值存入寄存器

    b.跳转

      push eip(压入返回地址,即函数调用返回后要执行的下一条指令的地址

      mv eip 函数的地址(将eip设置为被调用函数的地址,执行其代码区指令)

3.调用函数的逻辑代码

被调用函数的代码

  1.压入函数栈帧

  push ebp(压入旧栈帧的底部)

  mov ebp,esp(设置新栈帧的底部)

  sub esp,xxx(设置新栈帧的顶部)

2.被调用函数的逻辑(如果有返回值的话,存入寄存器)

3.弹出函数栈帧

  add xxx, esp(回收当前栈帧,栈顶指向旧栈帧底部值)
  pop ebp(将旧栈帧底部值位置恢复到ebp)

4.返回

  将eip设置为返回地址(返回到原函数)


寄存器值的特点:

  1.ebp始终标识当前栈帧的底部,不变。

  2.各个栈通过链表的方式串起来,"next指针"始终指向上一个栈帧的底部。

  3.esp标识当前栈帧的顶部,动态变化,也就是说,当前栈的大小在不断变化。


数据传递:

  调用函数和被调函数更可能通过寄存器交换参数和返回值,因为参数和返回值一旦被传递,寄存器又变成可用的。

地址跳转:

  调用函数:保存返回地址到被调函数的栈帧(返回地址必须一直被保存直到调用返回为止,不太可能使用寄存器来传递返回地址),并跳转到被调用函数的地址。

  被调函数:直接跳转到返回地址。

函数栈帧:

  被调用的函数会在开始时为自己建一个栈帧,并且在结束时销毁它,不过,所做的仅仅是设置ebp和esp的值。

 

posted on 2011-07-16 16:35  strugglEver  阅读(220)  评论(0)    收藏  举报