diff --git a/CMU-CSAPP/L07 Procedures 函数的调用.md b/CMU-CSAPP/L07 Procedures 函数的调用.md index 0340ebf..73b5197 100644 --- a/CMU-CSAPP/L07 Procedures 函数的调用.md +++ b/CMU-CSAPP/L07 Procedures 函数的调用.md @@ -1,4 +1,4 @@ -# Lecture 07 Procedures 函数的调用 +# Lecture 07 Procedures 过程 \(函数的调用\) ## Mechanisms 机制 / 目录 @@ -8,7 +8,7 @@ - [Passing Data 传递数据](#passing-data-传递数据) - [传入参数](#传入参数) - [返回值](#返回值) -- [Managing Local Data 管理其他变量](#managing-local-data-管理其他变量) +- [Managing Local Data 管理其他变量与内存](#managing-local-data-管理其他变量与内存) - [Stack Frame 栈帧](#stack-frame-栈帧) - [Recursion 递归](#recursion-递归) - [`ret` 指令](#ret-指令) @@ -97,20 +97,29 @@ 返回值一般使用```%rax```进行传递。 -## Managing Local Data 管理其他变量 +## Managing Local Data 管理其他变量与内存 ### Stack Frame 栈帧 -一般情况下,由于诸多与函数相关的特点,我们会在栈上分配一些内存给局部变量。加上其他要分配的内存[^extra-mmr-allocate],这部分被称作“栈帧”。 +有时,我们会在栈上分配一些内存给局部变量。常见情况比如: + +- 寄存器不够存放所有的局部变量 +- 某些局部变量是个Array或者Struct +- 对一个局部变量取地址(&),需要它在内存中有一个固定的地址 + +加上其他要分配的内存[^extra-mmr-allocate],这部分被称作“栈帧”。 | 函数特点 | 栈特点 | | ---------- | ---------- | | 返回后,函数内分配的局部变量被丢弃 | 更改```rsp```指针即可丢弃数据 | | 函数内可能会调用其他函数 | 直接将返回地址压栈 | | 单线程调用其他函数时,原函数停止继续运行 | 保存原函数 的帧指针,在其之上可直接建立新栈帧 | +| 原函数的数据保持不变 | 新分配一个栈即可避免数据被覆盖 | [^extra-mmr-allocate]: 上一个函数的寄存器内容、Windows下的影子空间、返回地址等等内容。 +需要注意的是,在C语言中,struct、union这种“庞大”的数据类型也会被留在栈上。如果处理不当,很可能Stack Overflow。因此,在处理大型数据结构时,通常建议使用动态内存分配(如malloc)来避免栈空间的过度使用,并使用free来手动释放。 + ### Recursion 递归 由于“栈帧”的特性,它很适合用来做递归。系统会为每一层递归单独分配内存空间,彼此之间不会因为相同的代码导致变量的地址也相同(使用```%rbp + 数```管理)。 diff --git a/README.md b/README.md new file mode 100644 index 0000000..a384486 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Overview + +这个仓库是学习CS的笔记。各个文件夹分别对应不同的课程,里面是我在学习过程中总结的笔记. + +This repository contains notes on various CS courses. Each folder corresponds to a different course, and inside are the notes I have compiled during my learning process.