一開始,看到 STMFD sp!{R0-R5,LR} 這條命令時真是有點疑惑。現根據自己的理解記錄一下。供大家分享!
我們先要理解一下關於堆棧的相關概念.
1,滿堆棧:即入棧後堆棧指標sp指向最後一個入棧的元素。也就是sp先減一(加一)再入棧。
2,空堆棧:即入棧後堆棧指標指向最後一個入棧元素的下一個元素。也就是先入棧sp再減一(或加一)。
1,遞增堆棧:即堆棧一開始的地址是低地址,向高地址開始遞增。就如同一個水杯(假設上面地址大)開口的是大地址,從杯底開始裝水。自己畫一畫圖就清楚了。我就偷懶一下不畫了。
2,遞減堆棧:即堆棧一開始的地址是高地址,向低地址開始遞增。就如同還是剛才說的那個水杯,現在開口的是小地址,從大地址開始用,往下走,相當於杯子口朝下。我們用的時候是把水往上一點點壓上去。呵呵呵,不過這樣的杯子就失去了用途。但在記憶體上還是可以的。
當然有這些類型就可以構成4種不同的堆棧方式。
還有就是,我們要明確一點就是arm的棧一般我們用滿堆棧、遞減堆棧。
下面說一下咱們的正題,STMFD sp!{R0-R5,LR}
STMFD 我解釋一下 ST(store 儲存) M(multiple 多次)F(full 滿堆棧)D(decrease 遞減堆棧) 合起來就是按滿的遞減的方式把後面的寄存器裡的值都存到sp中。
STMFD sp!{R0-R5,LR} 就這條就是 把 lr r5-r0 依次存到sp中,並且sp會在存資料之前自動減一個資料的空間(別忘了arm是遞減的哦)。至於最後一個問題,我想大家肯定還有一個疑惑就是sp後為什麼有一個“!”。是這樣的如果有 !號,表示在存入資料後sp會指向最後一個存入的資料的地址,否則sp會把自己的值加到一開始的地址。(就是sp在執行完這條指令之後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 |
我覺著掌握彙編指令一方面是多用,還有就是我們把彙編指令的英文全稱找到或自己按英文理解。這樣可能會對你理解這條語句有協助。
你可以把其他指令按我說的做一做。由於時間關係我就不一一列舉。