天天看点

c语言----栈帧

栈帧

  每一次函数调用都有一个过程,称为“函数调用过程”,这个过程要为函数开辟栈空间,用于本次函数的调用中临时变量的保存,现场保护。这个栈空间称为函数的调用过程。

  Ⅰ.寄存器

   基址寄存器(栈底寄存器):EBP

   栈顶寄存器:ESP

   通用寄存器:EAX,EDX,EBX,ECX.

Ⅱ.汇编指令:

  call:功能:1.将当前正在执行指令的下一条指令的地址压人栈中;2.随即call会跳转至指定函数(jmp)

  ret(返回):1.弹出(pop)栈顶;2.弹出后的栈顶元素放入EIP。

Ⅲ.研究代码

#include<stdio.h>

#include<windows.h>

int myadd(int x,int y)

{

int z = x + y;

return z;

}

int main()

{

int a = 0xAAAAAAAA;

int b = 0xBBBBBBBB;

int c = 0;

c = myadd(a,b);

printf("you should run here\n");

printf("result:%d\n",c);

system("pause");

return 0;

}

Ⅳ.栈帧过程:

1.main函数中的栈帧以及main函数调用时形参的实例化:

c语言----栈帧

2.返回把当前执行指令的下一条指令保存,esp中a的地址比b小:

c语言----栈帧

3.由反汇编得call指令的下一条指令的地址为0040109A,将它压入栈中,F11后下图中0019FEDC变为0040109A(小端)

c语言----栈帧
c语言----栈帧

通过jmp到指定函数myadd处  寄存器EIP变为00401020

c语言----栈帧

在myadd函数中:

c语言----栈帧

再把EBP mov 给esp得

mov前为:

c语言----栈帧

mov后为:

c语言----栈帧

此时ebp指向esp

c语言----栈帧

下一条指令00401023为给ESP-4,所以此时ESP要往下移,形成了一个新的空间,这个空间为myadd的栈帧。

c语言----栈帧

上面3条指令所表达的意思:

1.把ebp+8(a) mov 给eax;

2.把 ebp+12(b) 与eax相加为eax;

3.eax mov给 ebp-4,所以此时栈帧如下:

c语言----栈帧

函数调用完成之后

c语言----栈帧

把ESP mov 给ebp,弹出(pop)栈顶给ebp,所以此时的ebp为main函数的ebp,下一步返回ret,ret作用为弹出(pop)栈顶并把弹出后的栈顶值放入EIP。此时恢复到main函数的栈帧内,如下:

c语言----栈帧

最后如下:

c语言----栈帧

谢谢观看。

继续阅读