资料来源
第 19 章 汇编与C之间的关系 1. 函数调用
《 Linux C编程一站式学习》https://akaedu.github.io/book/ch19s01.html
主要心得
-
ebp寄存器要压栈,用ebp来取
传入参数
和局部变量
- 我对栈帧的理解,从进入当前函数到离开当前函数这个过程中,当前函数对
栈
造成的全部结果(压栈操作)叫做这个函数的栈帧 - 但是当前函数需要的传入参数是它的调用者压入的,也就是说传入参数在调用者的栈帧里面
-
ebp(当前函数)
是进入当前函数时的栈顶地址
(即这个时候的ESP的值) - 要时刻分清这个是B还是S
- 我们可以通过
ebp(当前函数)+X
达到向上去高地址从而拿到传入参数
1、回忆一下这三个寄存器
![](https://img.haomeiwen.com/i10191360/8988752de9d4c08e.png)
2、函数的调用 main -> foo -> bar
int bar(int c, int d)
{
int e = c + d;
return e;
}
int foo(int a, int b)
{
return bar(a, b);
}
int main(void)
{
foo(2, 3);
return 0;
}
2、大致看一眼栈的生长情况,栈随着函数调用的深入 从上往下生长
![](https://img.haomeiwen.com/i10191360/748774d1716dd2b2.png)
- 传入参数由调用者压栈
- 传入参数由
ebp(当前函数)+ X
向上取得 - 局部变量由当前函数压栈
- 局部变量由
ebp(当前函数) - X
向下取得 - 是e b p寄存器,基址寄存器,
Base Pointer
, 注意这个B ,注意这是B,不是S
3、完整的栈生长过程 (函数调用过程) 1->2->3->4
![](https://img.haomeiwen.com/i10191360/97afd418a14f284a.png)
-
call
指令的作用,包括函数返回地址压栈以及跳转 -
esp
的减小是压栈引起的,栈从高地址往低地址生长,压栈引起数值变小 -
ebp
寄存器的值与函数相关,ebp(main)
表示这是main函数的ebp
4、栈帧的串连
![](https://img.haomeiwen.com/i10191360/9bd3b432aa773112.png)
- 返回地址肯定是要压栈的,不然不知道怎么回来,回来到哪里
-
ebp也要压栈,对的这个B要压栈,要用来取
(调用者压入的)传入参数
和(当前函数压入的)局部变量
- esp这个S本身是不需要入栈的,一直在变化,它是栈顶
网友评论