详细解析ESP寄存器与EBP寄存器
参看 :http://www.tenouk.com/Bufferoverflowc/Bufferoverflow2a.html (英)
https://blog.csdn.net/u011822516/article/details/20001765 (中)
- ESP : 栈指针寄存器 (extended stack pointer) ,永远指向系统栈最上面一个栈帧的栈顶。
- EBP: 基址指针寄存器(extended base pointer), 永远指向系统栈最上面一个栈帧的栈底。
每一次函数的调用,都会在调用栈(call stack)上维护一个独立的栈帧(stack frame).
函数调用
参看:https://www.jianshu.com/p/b666213cdd8a
- 参数入栈: 将参数按照调用约定(C 是从右向左)依次压入系统栈中;
- 返回地址入栈: 将当前代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行;
- 代码跳转: 处理器将代码区跳转到被调用函数的入口处;
- 栈帧调整:
1.将调用者的ebp压栈处理,保存指向栈底的ebp的地址(方便函数返回之后的现场恢复),此时esp指向新的栈顶位置;push ebp
2.将当前栈帧切换到新栈帧(将eps值装入ebp,更新栈帧底部), 这时ebp指向栈顶,而此时栈顶就是old ebpmov ebp, esp
3.给新栈帧分配空间sub esp, XXX
函数返回
函数返回分为以下几步:
- 保存被调用函数的返回值到 eax 寄存器中
mov eax, xxx
- 恢复 esp 同时回收局部变量空间
mov ebp, esp
- 将上一个栈帧底部位置恢复到 ebp
pop ebp
- 弹出当前栈顶元素,从栈中取到返回地址,并跳转到该位置
ret
函数调用方式
- cdecl : C语言主要方式,调用者处理栈
- stdcall : win32 API,被调用者处理栈
- fastdll