【學習筆記】2. 函數調用的棧的管理

記在最初,若是發現有專業術語的錯誤,請記得及時改正。 這個真的很重要。

1. 無參數傳遞的函數調用

本例會實際演示一個 只有函數局部變量賦值的demo
會先看一下C語言源代碼和編譯代碼,而後一步一步的推演棧的空間使用

1.1 函數源碼

C語言源碼:html

clipboard.png

註釋: 這個腳本中,main 函數調用 f 函數,各自函數裏面有局部變量的定義,函數調用沒有參數傳遞。segmentfault

編譯代碼:函數

clipboard.png

clipboard.png

彙編指令:學習

clipboard.png

1.2 編譯step過程

0. 確認棧的地址

clipboard.png

爲了方便記憶和觀看,咱們先假設棧的其實地址是 9000優化

1. 肯定main函數的棧幀

clipboard.png

2. 保存局部變量

clipboard.png

若是變量 < 4 個,直接保存到寄存器。spa

變量數量 > 4 的部分放入到棧中。3d

具體的地址參數是視頻

clipboard.png

3. 跳轉到f函數

f 函數的第一步壓棧處理htm

clipboard.png

4. 確認f函數的棧幀

clipboard.png

5. 返回參數變量

返回的值,會直接放到 r0 寄存器上blog

若是值比較大,會開闢一個地址單元,把地址返回給主函數

clipboard.png

6. 返回到main函數

clipboard.png

clipboard.png

而後直接返回

經過這樣的操做,函數返回到 main 函數,上一個函數

7. 返回執行函數

可執行文件 使用 exec fork 子進程

main的上一個函數 是 execve

clipboard.png

把 execve 的地址 給 pC,下一條執行的 地址

clipboard.png

每一個棧幀上一個函數的起始地址 好比 9000

bl b 指令自動會函數 下一條地址 壓入棧

壓棧的都是在下一級須要改變的,要不編譯器會優化掉

2. 有傳參的函數調用

2.1 運行實例代碼

clipboard.png

對應的彙編代碼

clipboard.png

2.2 執行步驟

一、main 函數壓棧和入棧

clipboard.png

2. 存儲局部變量

clipboard.png

3. 傳參的入棧

clipboard.png

clipboard.png

4. 跳轉到f函數

clipboard.png

5. f函數的壓棧和入棧

clipboard.png

6. 傳參在f函數的保存

clipboard.png

clipboard.png

初始化 sum 值

clipboard.png

7. f函數變量的賦值

clipboard.png

clipboard.png

能夠發現此時改變的不是形參 n 而是 傳參的棧地址

8. 加法運算

clipboard.png

clipboard.png

9. 返回main函數

clipboard.png

fp 返回的是棧幀保存的上一個函數的地址

而後從新回到了 main 函數

因此並無改變實際參數的值,由於存儲到不一樣的位置單元。 傳參和定義的局部變量。 會保存棧或者寄存器的不一樣位置

3.形參和實參

結合上面 第二段的內容 形參和實參的分析
能夠看出,在調用函數進行參數傳遞的時候,會從新分配棧空間或者寄存器進行管理。
而同時被調用的函數(好比f函數),在初始化中,會先把寄存器中的值取出來,放到本身的棧裏面進行管理。

因此被傳入的參數和main函數中的,屬於不一樣的地址。所以也不會相互影響。

100. 致敬

若有不詳,請參考王老師的精彩講解 堆棧管理
學習過程當中,得到了極大的知足感,把以前的一些東西串聯了起來。十分感謝 王利濤老師。在此表示感謝。PS:本文中全部的資源和圖片均來自視頻中

相關文章
相關標籤/搜索