以此代码为例学习栈帧:
栈区:当前程序的地址空间
因此我们将栈区放大讨论。
现在我们运行上面的代码,并打开汇编讨论,如图:
当前汇编直接到main函数,
继续往下走,
这还是main函数中的变量a,b,现在我们在图中把各种寄存器写出来,图中的蓝色区域叫做该函数(当前为main函数)的栈帧
ebp:指向栈底。
esp:指向栈顶。
栈帧:我们将esp,ebp两个寄存器所表示的那一段内存空间称之为函数的栈帧
esp,ebp中存的是地址。
执行ebp-4,ebp-8,a,b各占4个字节
结论:常规情况下,先定义的变量地址高,后定义的变量地址低。(先入栈后出)
往下走就是调用函数myadd(a,b)
先将b移动到(mov)到eax中,eax入栈,继续将a移动到ecx中,ecx入栈
栈顶发生改变esp从0018FEF0到0018FEEC,即把esp下移4个字节,把b放入,再把a放入:
此时就形成了临时变量。那么临时变量实在什么时候形成的呢?是在call命令下形成的。
Call:1.将当前call命令的下一条地址保存起来,将其入栈,实现保存,保存的目的是为了恢复。
2.通过jmp修改eip达到跳转的目的。
记下当前add的地址:00401093
Call调完了,现在E4的栈顶地址指向00401093
这个地址其实是main函数add的
至此就进入到了add函数中
执行上面的汇编代码,a,b入栈。
下面执行x+y
add函数调用完,接下来就是执行出栈
临时变量在调用函数和被调用函数的栈帧之间。