1栈是什么
栈是一种 LIFO 形式的数据结构,所有的后进先出。这种方式正好满足我们调用函数的方式:父函数在前,子函数在后;返回时,子函数先返回,父函数后返回。栈支持两种基本操作 push 和 pop 。 push 将数据压入栈中, pop 将栈中的数据弹出并存储到指定寄存器或内存中。
2栈帧是什么
栈帧其本质就是一种栈,只是这种栈专门用于保存函数调用过程中的各种信息(参数,返回地址,本地变量等)。
栈帧有栈顶和栈底之分,其中栈顶的地址最低,栈底的地址最高, SP (栈指针)就是一直指向栈顶的。
3栈帧结构
函数调用经常是嵌套的,在同一时刻,堆树有多个函数的信息。每个未完成运行的函数占用一个独立的连续区域,称一,函数的调用
我们直接通过实例来看函数是如何调用的。这是一个有参数但没有调用任何函数的简单函数,我们假设它被其他函数调用。
int MyFunction ( int x , int y , int z ){ int a , b , c ; a =10; b =5; c =2;...} int TestFunction (){ int x =1, y =2, z =3;MyFunction1(1,2,3);...}对于这个函数,当调用时, MyFunction ()的汇编代码大致如下:
_ MyFunction : push % ebp ;//保存% ebp 的值 movl % esp ,$ ebp ;//将% esp 的值赋给% ebp ,使新的% ebp 指向栈顶 movl -12(% esp ),% esp ;//分配额外空间给本地变量 movl $10,-4(% eb p ); movl $5,-8(% ebp ); movl $2,-12(% ebp );此时调用者做了两件事情:第一,将被调用函数的参数按照从右到左的顺序压入栈中。第二,将返回地址压入栈中。这两件事都是调用者负责的,因此压入的栈应该属于调用者的栈帧。我们再来看看被调用者,它也做了两件事情:第一,将老的(调用者的)% ebp 压入栈,此时% es p 指向它。第二,将% esp 的值赋给% ebp bp 就有了新的值,它也指向存放老% ebpC 知道空间。这时,它成了是函数 MyFunction ()栈帧作栈帧( Stack Fram