ARM下C語言棧幀機制
背景:
最近在某個RTOS上遇到一個系統BUG,幾經折騰,終於將其斬於馬下。結局美好,過程卻很曲折,在分析定位問題的時候,順便把ARM上C函式呼叫stack frame機制捋了一遍,記錄並分享一下。
概念:
棧:
1)從資料結構的角度來理解,棧是一種描述先進後出的資料結構;
2)從程式的記憶體空間角度來理解,棧是一種特殊的記憶體段,用於存放區域性變數、函式引數、返回值等;
第一種角度,用來描述本身的特性,第二種角度,是將這種資料結構的特性用於實際的記憶體空間中。
棧幀:每個程式都會有自己的棧空間,而程式中的各個函式也會維護自己本身的一個棧的區域,這個區域就是棧幀。那麼一個函式的棧幀的區域是如何來界定的呢?當然,我首先會普及ARM的幾個特殊暫存器功能。
R11:frame pointer,FP暫存器
R12:IP暫存器,用於暫存SP
R13:stack pointer,SP暫存器
R14:link register,LR暫存器
R15:PC暫存器
而在ARM上,函式的棧幀是由SP暫存器和FP暫存器來界定的,相信你應該見過下邊這張比較經典的圖了:
上圖描述的是main函式呼叫func1函式的棧幀情況,從圖可知,當main函式呼叫func1函式時,func1函式會先將PC、LR、SP、FP四個暫存器壓到棧上邊,其中SP和FP的值分別指向main函式棧幀的兩個邊界,LR的值儲存的是func1呼叫結束之後的返回值,PC值表示的是當前執行到的指令地址,放置的是進入func1後的指令地址。緊接著就會在棧上分配一片區域,用於放置區域性變數等。
如果func1中還呼叫了func2子函式,那麼也會為func2建立一個棧幀,並且func2的SP和FP會指向func1棧幀的兩個邊界。這樣當函式返回的時候,引數進行出棧,也能找到Caller函式,這個也就是backtrace的原理了。
示例:
反彙編分析某段程式碼,如下圖所示:
紅色部分,表明進入到函式時先將幾個特殊的暫存器壓棧
黃色部分,sub sp, sp, #16,表明開闢一個4 x 32bit大小的棧區域
藍色部分,將傳入的引數壓棧,在ARM ATPCS中規定,暫存器R0-R3用來傳參
綠色部分,呼叫子函式
那麼,我們順道看看子函式的棧幀區域吧:
從圖中可以看出,機制是一樣的,當最終queue_push函式呼叫結束後,棧上的資料進行出棧,根據fp和ip,便能找到workflow_gather_input函式的棧幀了。
當然,並不是所有函式呼叫都需要先push {fp, ip, lr, pc},當子函式呼叫過程中,並不會去改變這些值的時候,就不需要壓棧,說白了,壓棧的目的就是為了在使用完的時候能恢復原來的狀態。我會再次提供一個例子:
strlen函式中沒有子函式的呼叫,所以進入函式後,直接就在棧上分配4 * 32bit大小的區域了。
棧裡邊能分析出每個引數的值,以及函式呼叫時的傳參,這對分析與定位問題很有幫助。成熟的系統可能會提供一堆工具來dump stack,並去分析呼叫關係,但是在RTOS上,很多卻並不完善,需要一定的低層知識去分析才能解決問題。
作者:Loyen
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4548/viewspace-2820959/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C語言函式呼叫棧C語言函式
- C#以及其他語言環境下的堆和棧C#
- 鏈式棧介面設計(C語言)C語言
- C語言資料結構:鏈式棧及其出入棧C語言資料結構
- C語言資料結構:順序棧的建立、出入棧,以及使用順序棧實現十進位制轉十六進位制C語言資料結構
- 資料結構 順序棧(c語言)資料結構C語言
- c語言 5.9.2下載C語言
- 組合語言-棧組合語言
- C語言進位制轉換與列印C語言
- 利用順序棧完成的作業題(C語言)C語言
- 包含min函式的棧(劍指offer)---C語言函式C語言
- c語言順序棧常規插入刪除操作C語言
- Go語言錯誤處理機制Go
- protobuf 在嵌入式ARM平臺的應用(c語言版)C語言
- 用 Go 語言實作 Job Queue 機制Go
- Linux下C語言驗證多程式LinuxC語言
- lec 02 arm組合語言基礎組合語言
- python 棧幀沙箱逃逸Python
- python棧幀沙箱逃逸Python
- C語言C語言
- 初學計算機語言者(C語言,C++,java,pytion,C#)計算機C語言C++JavaC#
- 聊聊C語言/C++—程式和程式語言C語言C++
- C語言編譯器手機版C語言編譯
- Go語言處理—Day11—反射機制Go反射
- Linux下跨語言呼叫C++實踐LinuxC++
- Linux下C語言編譯的問題LinuxC語言編譯
- 【C語言】linux下多檔案編譯C語言Linux編譯
- C語言資料結構(8)--棧 後進先出線性表C語言資料結構
- 棧 ADT 【資料結構與演算法分析 c 語言描述】資料結構演算法
- 關於10進位制轉2進位制的C語言程式碼C語言
- C語言 typedefC語言
- C語言(一)C語言
- C語言: returnC語言
- C語言字串C語言字串
- 偽隨機數C語言程式設計隨機C語言程式設計
- C語言與嵌入式C語言的區別C語言
- C語言學習方法,怎麼學習C語言?C語言
- Java語言概述022_JVM與垃圾收集機制JavaJVM