1. x86的函数调用规则
1.1 x86的寄存器说明
详细说明请参考:http://www.cnblogs.com/onroad/archive/2009/07/13/1522673.html
这里关心的只有:eax , ecx, edx,ebx四个数据寄存器和esp,ebp两个栈寄存器。
1.2 caller调用callee
首先会把参数压入到栈,第一个参数最后压入,所以在地址最低的位置。
然后返回地址压栈,jmp到callee的地址调用,这一步和call的作用相同。
进入到callee中,首先就是:
push ebp;原来的栈帧地址保存
mov ebp, esp;把ebp设置成现在的esp,所以返回地址在esp+4,第一个参数在esp+8,第二个参数在esp+12。。。
sub esp, xxx;esp栈顶下移一段,这段空间保存函数用到的局部变量等;
虽然有些局部变量保存在寄存器中,但对于要用到地址的局部变量就要保存在栈中,比如ebp-4 , ebp-8等。
push ebx;callee用到的寄存器都要先保存,但不需要eax,ecx,edx,这三个作为临时寄存器,callee可以随便用
最后恢复栈的原地址;
返回值放到eax,如果大于4字节可以用eax和edx,如果再大就放到栈中,caller会根据esp去取得;
ret;这条指令pop出返回地址然后跳转。</