# 第三章? 函數開始和結束
函數開始的指令,是像下面這樣的代碼片段:
```
#!bash
push ebp
mov ebp, esp
sub esp, X
```
這些指令做了什么:將寄存器EBP的值入棧,將ESP賦值給EBP,在棧中分配空間, 用來保存局部變量。
在函數執行過程中,EBP是固定的,可以用來訪問局部變量和函數參數。也可以使用 ESP,但在函數運行過程中,ESP會變化,使用起來不方便。
```
#!bash
mov esp, ebp
pop ebp
ret 0
```
函數在運行結束時,會釋放在棧中所申請的內存,EBP的值出棧,將代碼控制權還原 給調用者。
## 3.1 遞歸
函數調用開始和結束使遞歸變得難以理解。
舉個例子,有一次我寫了一個函數遍歷二叉樹右側節點。使用了看起來很高?上的遞歸函數,但由于每次函數調用開始和結束都需要花費很長時間,它運行速度比迭代方 式要慢好多倍。
順便提一下,這就是尾部調用存在的原因。
- 第一章 CPU簡介
- 第二章 Hello,world!
- 第三章? 函數開始和結束
- 第四章 棧
- Chapter 5 printf() 與參數處理
- Chapter 6 scanf()
- CHAPER7 訪問傳遞參數
- Chapter 8 一個或者多個字的返回值
- Chapter 9 指針
- Chapter 10 條件跳轉
- 第11章 選擇結構switch()/case/default
- 第12章 循環結構
- 第13章 strlen()
- Chapter 14 Division by 9
- chapter 15 用FPU工作
- Chapter 16 數組
- Chapter 17 位域
- 第18章 結構體
- 19章 聯合體
- 第二十章 函數指針
- 第21章 在32位環境中的64位值
- 第二十二章 SIMD
- 23章 64位化
- 24章 使用x64下的SIMD來處理浮點數
- 25章 溫度轉換
- 26章 C99的限制
- 27章 內聯函數
- 第28章 得到不正確反匯編結果
- 第29章 花指令
- 第30章 16位Windows
- 第31章 類
- 三十二 ostream