没有栈就没有函数,没有局部变量,传统上其是一个特殊的容器,用户将数据压入栈中,也可以将数据弹出,遵循先入后出的原则。
也就是说是一个动态的内存区域,压栈增大了栈,出栈减少了栈。
通常esp寄存器定位栈顶部,压栈使得栈顶地址变小,弹出反之增大,因为从高地址开始。
减少esp等于在栈上开辟空间,反之就是回收空间。
栈在程序运行时,保存了函数所需要的维护信息,也就是堆栈帧,或者说活动记录,里面包含了函数的返回地址和参数,临时变量,包括非静态的局部变量,和编译器自动生成的其他临时变量。还保存了上下文,还由函数调用前后需要保持不变的寄存器。
一般就是esp和ebp两个寄存器,esp指向栈顶部,ebp指向了函数活动记录的一个固定的位置,也叫做帧指针。
一般来说一个函数的汇编代码开头应该是:
push ebp;把ebp(old ebp)压入栈
move ebp ,esp;这时候ebp指向栈顶,这时候栈顶是old ebp,也就是保存了旧的栈顶置针
返回的时候再把ebp给esp,从而获得初始入栈的时候的函数信息。
一些函数前几个字节会预留一些空字节,这样就可以动态的插入一个jmp指令,从而跳转到另外一个函数,那么我们就可实现一个简单hook