add README.md and update L07 note
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Lecture 07 Procedures 函数的调用
|
# Lecture 07 Procedures 过程 \(函数的调用\)
|
||||||
|
|
||||||
## Mechanisms 机制 / 目录
|
## Mechanisms 机制 / 目录
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
- [Passing Data 传递数据](#passing-data-传递数据)
|
- [Passing Data 传递数据](#passing-data-传递数据)
|
||||||
- [传入参数](#传入参数)
|
- [传入参数](#传入参数)
|
||||||
- [返回值](#返回值)
|
- [返回值](#返回值)
|
||||||
- [Managing Local Data 管理其他变量](#managing-local-data-管理其他变量)
|
- [Managing Local Data 管理其他变量与内存](#managing-local-data-管理其他变量与内存)
|
||||||
- [Stack Frame 栈帧](#stack-frame-栈帧)
|
- [Stack Frame 栈帧](#stack-frame-栈帧)
|
||||||
- [Recursion 递归](#recursion-递归)
|
- [Recursion 递归](#recursion-递归)
|
||||||
- [`ret` 指令](#ret-指令)
|
- [`ret` 指令](#ret-指令)
|
||||||
@@ -97,20 +97,29 @@
|
|||||||
|
|
||||||
返回值一般使用```%rax```进行传递。
|
返回值一般使用```%rax```进行传递。
|
||||||
|
|
||||||
## Managing Local Data 管理其他变量
|
## Managing Local Data 管理其他变量与内存
|
||||||
|
|
||||||
### Stack Frame 栈帧
|
### Stack Frame 栈帧
|
||||||
|
|
||||||
一般情况下,由于诸多与函数相关的特点,我们会在栈上分配一些内存给局部变量。加上其他要分配的内存[^extra-mmr-allocate],这部分被称作“栈帧”。
|
有时,我们会在栈上分配一些内存给局部变量。常见情况比如:
|
||||||
|
|
||||||
|
- 寄存器不够存放所有的局部变量
|
||||||
|
- 某些局部变量是个Array或者Struct
|
||||||
|
- 对一个局部变量取地址(&),需要它在内存中有一个固定的地址
|
||||||
|
|
||||||
|
加上其他要分配的内存[^extra-mmr-allocate],这部分被称作“栈帧”。
|
||||||
|
|
||||||
| 函数特点 | 栈特点 |
|
| 函数特点 | 栈特点 |
|
||||||
| ---------- | ---------- |
|
| ---------- | ---------- |
|
||||||
| 返回后,函数内分配的局部变量被丢弃 | 更改```rsp```指针即可丢弃数据 |
|
| 返回后,函数内分配的局部变量被丢弃 | 更改```rsp```指针即可丢弃数据 |
|
||||||
| 函数内可能会调用其他函数 | 直接将返回地址压栈 |
|
| 函数内可能会调用其他函数 | 直接将返回地址压栈 |
|
||||||
| 单线程调用其他函数时,原函数停止继续运行 | 保存原函数 的帧指针,在其之上可直接建立新栈帧 |
|
| 单线程调用其他函数时,原函数停止继续运行 | 保存原函数 的帧指针,在其之上可直接建立新栈帧 |
|
||||||
|
| 原函数的数据保持不变 | 新分配一个栈即可避免数据被覆盖 |
|
||||||
|
|
||||||
[^extra-mmr-allocate]: 上一个函数的寄存器内容、Windows下的影子空间、返回地址等等内容。
|
[^extra-mmr-allocate]: 上一个函数的寄存器内容、Windows下的影子空间、返回地址等等内容。
|
||||||
|
|
||||||
|
需要注意的是,在C语言中,struct、union这种“庞大”的数据类型也会被留在栈上。如果处理不当,很可能Stack Overflow。因此,在处理大型数据结构时,通常建议使用动态内存分配(如malloc)来避免栈空间的过度使用,并使用free来手动释放。
|
||||||
|
|
||||||
### Recursion 递归
|
### Recursion 递归
|
||||||
|
|
||||||
由于“栈帧”的特性,它很适合用来做递归。系统会为每一层递归单独分配内存空间,彼此之间不会因为相同的代码导致变量的地址也相同(使用```%rbp + 数```管理)。
|
由于“栈帧”的特性,它很适合用来做递归。系统会为每一层递归单独分配内存空间,彼此之间不会因为相同的代码导致变量的地址也相同(使用```%rbp + 数```管理)。
|
||||||
|
|||||||
Reference in New Issue
Block a user