記在最初,若是發現有專業術語的錯誤,請記得及時改正。 這個真的很重要。
本例會實際演示一個 只有函數局部變量賦值的demo
會先看一下C語言源代碼和編譯代碼,而後一步一步的推演棧的空間使用
C語言源碼:html
註釋: 這個腳本中,main 函數調用 f 函數,各自函數裏面有局部變量的定義,函數調用沒有參數傳遞。segmentfault
編譯代碼:函數
彙編指令:學習
爲了方便記憶和觀看,咱們先假設棧的其實地址是 9000優化
若是變量 < 4 個,直接保存到寄存器。spa
變量數量 > 4 的部分放入到棧中。3d
具體的地址參數是視頻
f 函數的第一步壓棧處理htm
返回的值,會直接放到 r0 寄存器上blog
若是值比較大,會開闢一個地址單元,把地址返回給主函數
而後直接返回
經過這樣的操做,函數返回到 main 函數,上一個函數
可執行文件 使用 exec fork 子進程
main的上一個函數 是 execve
把 execve 的地址 給 pC,下一條執行的 地址
每一個棧幀上一個函數的起始地址 好比 9000
bl b 指令自動會函數 下一條地址 壓入棧
壓棧的都是在下一級須要改變的,要不編譯器會優化掉
對應的彙編代碼
初始化 sum 值
能夠發現此時改變的不是形參 n 而是 傳參的棧地址
fp 返回的是棧幀保存的上一個函數的地址
而後從新回到了 main 函數
因此並無改變實際參數的值,由於存儲到不一樣的位置單元。 傳參和定義的局部變量。 會保存棧或者寄存器的不一樣位置
結合上面 第二段的內容 形參和實參的分析
能夠看出,在調用函數進行參數傳遞的時候,會從新分配棧空間或者寄存器進行管理。
而同時被調用的函數(好比f函數),在初始化中,會先把寄存器中的值取出來,放到本身的棧裏面進行管理。
因此被傳入的參數和main函數中的,屬於不一樣的地址。所以也不會相互影響。
若有不詳,請參考王老師的精彩講解 堆棧管理
學習過程當中,得到了極大的知足感,把以前的一些東西串聯了起來。十分感謝 王利濤老師。在此表示感謝。PS:本文中全部的資源和圖片均來自視頻中