函数调用过程初探
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的值。
浙公网安备 33010602011771号