在學校或者各種編程類書本上,基本上都會看到一句話:"函數是程序的基本組成單位",可以說理解函數對編程是非常重要的,與函數調用緊密結合的機制就是函數調用棧了,而棧有一個特別的屬性就是棧的增長方向問題了,也發現一些多年編程經驗的朋友對這一塊都有點迷迷糊糊的。在閱讀RTOS源碼的時候也會經常看到棧的增長方向配置項目,那么今天就帶大家了解一下棧的增長方向到底是咋回事。
1、棧的增長方向
首先我們要明確的是棧同樣也是分布在我們的內存之中,而內存是通過地址來進行編排訪問的,如下是堆棧的示意圖:
對于堆棧而言原本并沒有方向一說,只有入棧和出棧一說,程序中執行push指令則棧頂向上移動,執行pop指令則棧頂向下移動,其僅僅只是一種先進后出的數據結構,增長方向都是從棧底向棧頂方向移動,即分配數據的過程。
而我們平時所說的棧的增長方向又是怎么回事呢?
為了在內存中分配一段內存給堆棧,我們必須要區分堆棧相對于內存的地址而言的方向性,通常棧頂增長的方向是從內存的低地址向高地址變化,我們則稱為向上增長;反之則向下增長。
所謂"水往高處流,即向上增長",這樣應該就很好記憶了。
2、有什么用?
當了解處理器中棧指針的增長方向以后,我們在debug程序的時候才能真正的把控程序的運行過程。
在移植RTOS的過程中我們都需要對每個任務的堆棧分配一個合適的連續內存區域來使用,此時初始狀態堆棧指針指向什么位置就跟堆棧的增長方向密切相關,有過RTOS移植經驗的朋友應該都有在RTOS配置項中關注過這塊的選擇。
RTOS在任務初始化的時候,其堆棧指針應該指向其棧底位置,那么對于堆棧向上增長,任務初始化的時候我們需要把堆棧指針設置在所分配內存的低地址內存處,反之則設置到高地址處。
設置好以后,其在堆棧分配的過程中才會朝著所分配的內存區域中,否則就會堆棧反向自爆,導致程序異常;如果你的堆棧分配不合理,同樣了解堆棧變化方向后也變得有跡可循。
同樣在裸機程序中也需要了解一下處理器的堆棧變化方向,從而用來排查一些堆棧溢出所導致的程序異常問題。
3、用C語言如何判斷?
要了解一個CPU的堆棧的變換方向,一方面就是查詢相應的芯片參考手冊,另外一方面就是實際測試了。
畢竟堆棧也就是內存,自然就可以通過堆棧的分配過程取出所分配的內存地址來比較判斷,而C語言可以方便的訪問內存,也就比較容易判斷當前處理器中堆棧指針的增長方向了。
那還不簡單,直接在函數內部先后定義兩個局部變量,直接比較兩個變量的地址大小不就搞定了嗎?其實這種方式是依賴于編譯器實現的,畢竟哪個變量先進行內存申請,并沒有太大的影響。
那么是否有一種方法不依賴于編譯器實現呢?
必須有的,那就是函數調用棧了,因為先調用的函數必然首先入棧。
基于這樣的思想,這里bug菌寫一個判斷堆棧增長方向的demo供大家參考:
可以拿去試一試,看看你的芯片堆棧咋變化的~
審核編輯:劉清
-
處理器
+關注
關注
68文章
19259瀏覽量
229653 -
芯片
+關注
關注
455文章
50714瀏覽量
423156 -
C語言
+關注
關注
180文章
7604瀏覽量
136694 -
RTOS
+關注
關注
22文章
811瀏覽量
119595
發布評論請先 登錄
相關推薦
評論