1.函数实参怎么传给形参?形参有没有开辟内存?如果形参开辟内存,在哪里开辟的? 2.函数的返回值怎么返回到调用方函数? 3.函数返回后怎么知道从哪条语句开始继续执行?
首先看一段简单的代码: 首先来看下在调用点的汇编指令
rt = sum(a1,b1); 0040108D mov eax,dword ptr [ebp-8] 00401090 push eax 00401091 mov ecx,dword ptr [ebp-4] 00401094 push ecx 00401095 call @ILT+0(sum) (00401005) 0040109A add esp,8 0040109D mov dword ptr [ebp-0Ch],eax
call指令在调用时有两步: 1.压入下一行指令地址 0040109A 2.jmp跳转到sum函数栈帧中
下面是进入sum函数栈帧前的main函数的栈帧布局 可以看到形参变量a,b开辟了内存空间,是在调用方开辟的。 再看下进入sum函数后栈帧布局 函数退栈 return后返回值赋给了eax寄存器,由eax寄存器带回main函数赋给rt。 紧接着出栈了sum函数栈顶的三个寄存器。 然后看 mov esp,ebp这条指令,这条指令将esp指向的地址指向了ebp指向的地址。这条指令就是将开始进入sum函数开辟的一些内存“清理”掉了。 接下来pop ebp这条指令,是将当前栈顶的数据出栈并赋给ebp。现在当前栈顶的数据是main函数的栈底地址。也就是sum函数调用完成后能返回到main函数栈帧上来。 最后执行ret指令,这个过程中执行了一个pop指令,将当前栈顶的数据出栈并赋给下一行指令寄存器。当前的栈底数据是main函数调用sum函数的call指令的下一条指令地址。也就是add esp,8这条指令的地址0040109A。回到main函数后就可以接着下一条指令继续执行。