arm堆棧的增長方式


參考一

堆棧是一種數據結構,按先進後出(First In LastOut,FILO)的方式工作,使用一個稱作堆棧指針的專用寄存器指示當前的操作位置,堆棧指針總是指向棧頂。
當堆棧指針指向最後壓入堆棧的數據時,稱爲滿堆棧(FullStack),而當堆棧指針指向下一個將要放入數據的空位置時,稱爲空堆棧(Empty Stack)。
同時,根據堆棧的生成方式,又可以分爲遞增堆棧(AscendingStack)和遞減堆棧(DecendingStack),當堆棧由低地址向高地址生成時,稱爲遞增堆棧,當堆棧由高地址向低地址生成時,稱爲遞減堆棧。這樣就有四種類型的堆棧工作方式,ARM微處理器支持這四種類型的堆棧工作方式,即:
◎ Full descending 滿遞減堆棧
堆棧首部是高地址,堆棧向低地址增長。棧指針總是指向堆棧最後一個元素(最後一個元素是最後壓入的數據)。
ARM-Thumb過程調用標準和ARM、Thumb C/C++ 編譯器總是使用Full descending 類型堆棧。
◎ Full ascending 滿遞增堆棧
堆棧首部是低地址,堆棧向高地址增長。棧指針總是指向堆棧最後一個元素(最後一個元素是最後壓入的數據)。
◎ Empty descending 空遞減堆棧
堆棧首部是低地址,堆棧向高地址增長。棧指針總是指向下一個將要放入數據的空位置。
◎ Empty ascending 空遞增堆棧
堆棧首部是高地址,堆棧向低地址增長。棧指針總是指向下一個將要放入數據的空位置。

堆棧類型 入棧指令 出棧指令
Full descending STMFD (STMDB) LDMFD (LDMIA)
Full ascending STMFA (STMIB) LDMFA (LDMDA)
Empty descending STMED (STMDA) LDMED (LDMIB)
Empty ascending STMEA (STMIA) LDMEA (LDMDB)
例子:
STMFD r13!, {r0-r5} ; Push onto a Full Descending Stack
LDMFD r13!, {r0-r5} ; Pop from a Full Descending Stack.

參考二

堆棧嚴格來說應該叫做棧,棧(Stack)是限定僅在一端進行插入或刪除操作的線性表。因此,對棧來說,可以進行插入或刪除操作的一端端稱爲棧頂(top),相應地,另一端稱爲棧底(bottom)。不含元素的空表稱爲空棧。由於堆棧只允許在一端進行操作,因而按照後進先出(LIFO-LastIn First Out)的原理運作。
     從棧頂的定義來看,棧頂的位置是可變的。空棧時,棧頂和棧底重合;滿棧時,棧頂離棧底最遠。ARM爲堆棧提供了硬件支持,它使用一個專門的寄存器(堆棧指針)指向堆棧的棧頂。而且7種模式都有各自獨立的堆棧指針,也就是有各自獨立的堆棧空間。但這裏的堆棧和uC/OS操作系統的任務堆棧又有區別,uC/OS的每個任務都有自己的堆棧,要是把uC/OS移植到ARM上,可以藉助ARM的堆棧指針來實現。存儲器堆棧可分爲兩種:
                 向上生長:向高地址方向生長,稱爲遞增堆棧
                 向下生長:向低地址方向生長,稱爲遞減堆棧
     堆棧指針指向最後壓入的堆棧的有效數據項,稱爲滿堆棧;堆棧指針指向下一個要放入的空位置,稱爲空堆棧。這樣就有4中類型的堆棧表示遞增和遞減的滿堆棧和空堆棧的各種組合。

     滿遞增:堆棧通過增大存儲器的地址向上增長,堆棧指針指向內含有效數據項的最高地址。指令如LDMFA,STMFA等。
     空遞增:堆棧通過增大存儲器的地址向上增長,堆棧指針指向堆棧上的第一個空位置。指令如LDMEA,STMEA等。

     滿遞減:堆棧通過減小存儲器的地址向下增長,堆棧指針指向內含有效數據項的最低地址。指令如LDMFD,STMFD等。
     空遞減:堆棧通過減小存儲器的地址向下增長,堆棧指針指向堆棧下的第一個空位置。指令如LDMED,STMED等。

     爲什麼說“向上生長”和“向下生長”呢?那是以爲,一般畫堆棧示意圖都是把低地址畫在下面,高地址畫在上面。如下圖。
arm中堆棧指針的理解
 有一點需要注意的是,雖然ARM處理器覈對於兩種生長方式的堆棧均支持,但ADS的C語言編譯器僅支持一種方式,即從上往下長,並且必須是滿遞減堆棧。所以STMFD等指令用的最多。



發佈了34 篇原創文章 · 獲贊 57 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章