什么是栈帧 :
- 栈帧就是一个函数执行的环境:函数调用框架、函数参数、函数的局部变量、函数执行完后返回到哪里等等,栈是从高地址向低地址延伸的。
- 每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。
- 寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)
名词解释:
寄存器和一些汇编指令
名称 | 参数说明 |
---|---|
EAX | 累加(Accumulator)寄存器,常用于函数返回值 |
EBX | 基址(Base)寄存器,以它为基址访问内存 |
ECX | 计数器(Counter)寄存器,常用作字符串和循环操作中的计数器 |
EDX | 数据(Data)寄存器,常用于乘除法和I/O指针 |
ESI | 源变址寄存器 |
DSI | 目的变址寄存器 |
ESP | 堆栈(Stack)指针寄存器,指向堆栈顶部 |
EBP | 基址指针寄存器,指向当前堆栈底部 |
EIP | 指令寄存器,指向下一条指令的地址 |
call | 1将当前指令的下一条指令保存,保存的目的是为了恢复(入栈保存;2跳转至目标函数的地址处; |
ret | 1将当前栈顶的内容出栈;2用该内容修改eip |
入栈push和出栈pop
- push ebp就等于将ebp的值保存到栈中,并且将当前esp下移
- pop ebp就等于将ebp的值从栈中取出来,将ebp指向这个值
通过一段代码查看函数调用过程
1 | 1 |
GDB调试结果
1 | //对应源码第3行 |
如图所示:
1 | //对应源码第8行 |
如图所示:
1 | ##### 对应源码第3行 |
如图所示:
1 | 0x0000000000400556 in main () at tst.c:12 |
如图所示:
- 此时函数整个调用过程就结束了,main函数栈恢复到了调用之前的状态