标签:分配 实参 inf sum 指令 src 需要 调用 时间
特别说明该表示是基于IA-32指令系统,x86 64指令系统不同于IA-32
可执行文件的存储器映像
调用过程
IA-32的寄存器使用约定
– 调用者保存寄存器:EAX、EDX、ECX
当过程P调用过程Q时,Q可以直接使用这三个寄存器,不用
将它们的值保存到栈中。如果P在从Q返回后还要用这三个寄
存器的话,P应在转到Q之前先保存,并在从Q返回后先恢复
它们的值再使用。
– 被调用者保存寄存器:EBX、ESI、EDI
Q必须先将它们的值保存到栈中再使用它们,并在返回P之前
恢复它们的值。
– EBP和ESP分别是帧指针寄存器和栈指针寄存器,分别用来指
向当前栈帧的底部和顶部。
过程调用过程中栈和栈帧的变化 (Q为被调用过程)
过程解析
一个C过程的大致结构如下:
– 准备阶段
• 形成帧底:push指令 和 mov指令
• 生成栈帧(如果需要的话):sub指令 或 and指令
• 保存现场(如果有被调用者保存寄存器) :mov指令
– 过程(函数)体
• 分配局部变量空间,并赋值
• 具体处理逻辑,如果遇到函数调用时
– 准备参数:将实参送栈帧入口参数处
– CALL指令:保存返回地址并转被调用函数
• 在EAX中准备返回参数
– 结束阶段
• 退栈:leave指令 或 pop指令
• 取返回地址返回:ret指令
int nn_sum ( int n) { int result; if (n<=0 ) result=0; else result=n+nn_sum(n-1); return result; }
我们可以看出来,递归函数在不断的压栈生成栈帧,且没有到达最后一个递归的函数,他的栈帧并没有进行释放,所以
递归函数的空间和时间的开销都非常大(当达到他的极限值就会出现暴栈的情况)我们可以尽量不适用递归函数
标签:分配 实参 inf sum 指令 src 需要 调用 时间
原文地址:https://www.cnblogs.com/chenxuming/p/9689119.html