多寄存器加載/存儲指令的8種模式如下表所示,右邊四種為堆棧操作、左邊四種為數據傳送操作。
模式 說明模式 說明
IA 每次傳送后地址加4 FD 滿遞減堆棧
IB 每次傳送前地址加4 ED 空遞減堆棧
DA 每次傳送后地址減4 FA 滿遞增堆棧
DB 每次傳送前地址減4 EA 空遞增堆棧
數據塊傳送操作 堆棧操作
進行數據復制時,先設置好源數據指針和目標指針,然后使用塊拷貝尋址指令LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB進行讀取和存儲。
進行堆棧操作操作時,要先設置堆棧指針(SP),然后使用堆棧尋址指令STMFD/LDMFD 、STMED/LDMED、STMFA/LDMFA和STMEA/LDMEA實現堆棧操作。
當堆棧指針指向最后壓入堆棧的數據時,稱為滿堆棧(Full Stack);
本文引用地址:
http://cqxgywz.com/article/201611/320503.htm當堆棧指針指向下一個將要放入數據的空位置時,稱為空堆棧(Empty Stack)。
同時,根據堆棧的生成方式,又可以分為遞增堆棧(Ascending Stack)和遞減堆棧(DecendingStack)。
當堆棧由低地址向高地址生成時,稱為遞增堆棧,當堆棧由高地址向低地址生成時,稱為遞減堆棧。
這樣就有四種類型的堆棧工作方式,ARM 微處理器支持這四種類型的堆棧工作方式,
即:
◎ Full descending 滿遞減堆棧——FD 堆棧首部是高地址,堆棧向低地址增長。棧指針總是指向堆棧最后一個元素(最后一個元素是最后壓入的數據)。 ARM-Thumb過程調用標準和ARM、Thumb C/C++ 編譯器總是使用Full descending 類型堆棧。
◎ Full ascending 滿遞增堆棧——FA 堆棧首部是低地址,堆棧向高地址增長。棧指針總是指向堆棧最后一個元素(最后一個元素是最后壓入的數據)。
◎ Empty descending 空遞減堆棧——ED 堆棧首部是高地址,堆棧向低地址增長。棧指針總是指向下一個將要放入數據的空位置。
◎ Empty ascending 空遞增堆棧——EA 堆棧首部是低地址,堆棧向高地址增長。棧指針總是指向下一個將要放入數據的空位置。
在ARM中,一般是滿堆棧,堆棧生長方向是從上向下遞減的(51相反為遞增),在操作系統的一直過程中,與CPU相關部分的一直肯定會涉及到堆棧生長方向的定義。
在ARM中我們定義如下:
#define OS_STK_GROWTH 1 //從上向下遞減 UCOS51中相同的定義如下:
#define OS_STK_GROWTH 0 //從下向上遞增
arm堆棧的組織結構是 滿棧降 的形式,滿棧即sp是要停留在最后一個進棧元素,降:就是堆棧的增長方向是從高地址向低地址發展。 arm對于堆棧的操作一般采用 LDMFD(pop)和STMFD (push) 兩個命令。 以前困惑的就是STMFD 命令 對于操作數是按照什么順序壓棧的
比如:STMFD sp!{R0-R5,LR} 進棧順序是:
高地址(1方式) LR R5 R4 ``````` R0 <-sp 低地址
高地址(2方式) R0 R1 ``` R5 LR <-sp 低地址
現在通過下表,可以輕松的解決這個問題:
| 尋址方式 | 說明 | pop | =LDM | push | =STM |
| FA | 遞增滿 | LDMFA | LDMDA | STMFA | STMIB |
| FD | 遞減滿 | LDMFD | LDMIA | STMFD | STMDB |
| EA | 遞增空 | LDMEA | LDMDB | STMEA | STMIA |
| ED | 遞減空 | LDMED | LDMIB | STMED | STMDA |
可以輕松的解決這個問題: 尋址方式說明 pop =LDM push =STM FA 遞增滿 LDMFA LDMDA STMFA STMIB FD 遞減滿 LDMFD LDMIA STMFD STMDB EA 遞增空 LDMEA LDMDB STMEA STMIA ED 遞減空 LDMED LDMIB STMED STMDA 按照圖表,可知 STMFD對應的是STMDB,根據arm指令手冊,可知STMDB入棧順序是(1方式)而LDMFD對應的是LDMIA,這樣這兩個操作就可以成功配對:
評論