程序的虚拟地址空间

image-20240403210900001

在了解函数的栈帧之前,我们先了解一下虚拟地址空间的概念。操作系统给每个c语言程序实例分配了一块虚拟地址空间,营造了一种每个程序都独占则内存的假象。这块内存地址的分布如下。

栈区

栈是一种先进后出的数据结构。在C程序的地址空间中,%esp寄存器指向栈顶,%ebp寄存器指向栈底。栈由高地址向低地址延申,入栈时esp向低地址处移动,出栈时esp向高地址处移动

image-20240413140207649

函数的调用依赖于栈。调用函数,栈增加。函数返回,栈缩小。

函数调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
```





![image-20240413140907149](C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20240413140907149.png)

调用函数的过程本质上是修改PC(程序计数器)的值,PC指向了下一条执行指令的地址

在调用函数前

1. 参数从右往左依次入栈,
2. call指令将返回地址入栈,用于指明当函数返回时下一条执行语句

## 参数传递



32位的系统中,参数的传递是靠栈来进行的。

在X86-64架构中函数的参数是存储在寄存器中的,分别存储在di,si,dx,cx,r8,r9寄存器中。如果函数的参数大于6,超过的部分需要使用栈来进行传递

![image-20240403211624970](https://cdn.jsdelivr.net/gh/qianxiaolin/picgo/202404032116531.png)

## 局部变量

```c
long caller()
{
long argl = 534;
long arg2 = 1057;
long sum= swap_add(&argl, &arg2);
long diff = argl -arg2;
return sum* diff;
}

对应汇编代码

1
2
subq $16, %rsp 
movq $534, (%rsp)

创建局部变量