ARM彙編指令級

一.指令與僞指令

指令:CPU機器指令的助記符,經過編譯後會得到一串10組成的機器碼,可以由CPU讀取執行。
僞指令:本質上不是指令(只是和指令代碼一起寫在代碼中),它是編譯器環境提供的,目的是用來指導編譯過程,經過編譯後僞指令最終不會生成機器碼。

二:ARM彙編特點:

2.1:LDR/STR架構

ARM採用RISC架構,CPU本身不能直接讀取內存,而需要先將內存中內容加載入CPU中通用寄存器中才能被CPU處理。

ldr(load register)指令將內存內容加載入通用寄存器
str(store register)指令將寄存器內容存入內存空間中

ldr/str組合用來實現ARM CPU和內存數據交換

2.2:8種尋址方式

寄存器尋址: 寄存器r2的值賦給r1
mov r1, r2

立即尋址: 把0xFF00給r0寄存器
mov r0, #0xFF00

寄存器移位尋址: 把r1左移三位後賦值給r0
mov r0, r1, lsl #3

寄存器間接尋址: r2類似一個指針,r2指向一個內存地址,[]類似於C間接尋址,將r2指向內存的值賦給r1寄存器
ldr r1, [r2]

基址變址尋址: r2所指向的地址偏移4位後的內存地址賦給r1
ldr r1, [r2, #4]

多寄存器尋址: r1裏面放了內存地址,類似於數組,r1裏面7個元素,依次放到寄存器裏面
ldmia r1!, {r2-r7, r12}

堆棧尋址: sp棧指針,連續訪問數據放到寄存器
stmfd sp!, {r2-r7, lr}

相對尋址: 標號跳轉到標號執行
beq flag
flag:

2.3:條件後綴執行

mov r0,r1: 相當於C中的r0=r1
moveq r0,r1: 如果eq後綴成立,則直接執行mov r0,r1;如果eq本身不成立則本句代碼直接作廢,相當於沒有。類似與C語言中的if(eq)(r0 = r1;)

條件後綴執行注意2點:
1、條件後綴是否成立,不是取決於本句代碼,而是取決於這句代碼之前的代碼運行後的結果。
2、條件後綴決定了本句代碼是否被執行,而不會影響上一句和下一句代碼是否被執行

三:一些特殊指令

3.1 mvn:

mvn和mov用法一樣,mov是原封不動的傳遞,而mvn是按位取反後傳遞
譬如r1=0xff ,然後mov r0,r1後,r0 = 0xff 但是mvn r0,r1後,r0=0xff000000

and 邏輯與
orr 邏輯或
eor 邏輯異或

3.2 bic位清除指令

bic r0,r1,#0x1f @將r1中的數bit0到bit4清零後賦值給r0

3.3 比較指令cmp,cmn

比較指令:
cmp cmp r0,r1 等價於 sub r2,r0,r1(r2 = r0 - r1)
cmn cmn r0,r1 等價於 add r0,r1

比較指令用來比較2個寄存器中的數
注意:比較指令不用後加s後綴就可以影響cpsr中的標誌位

3.4 cpsr和spsr的區別和聯繫:

cpsr是程序狀態寄存器,整個SoC中只有1個;而spsr有5個,分別在5種異常模式下,作用是當從普通模式進入異常模式時,用來保存之前普通模式下的cpsr的,以在返回普通模式時恢復原來的cpsr.

cpsr訪問指令:
mrs & msr
mrs用來讀psr,msr用來寫
cpsr寄存器比較特殊,需要專門的指令訪問,這就是mrs和msr.

舉個例子:

@IRQ & FIQ disable
mrs  r0,cpsr  @cpsr讀到r0
bic  r0,r0,#0x1f    @bit0到bit5清除
orr  r0,r0,#0xd3    @位或0xd3  11010011  (I & F disable and 10011模式) 查看cpsr程序狀態寄存器
msr  cpsr,r0    @r0寫進cpsr

3.5 跳轉指令:

b直接跳轉

bl(跳轉前把返回地址放入lr中,以便返回,以便用於函數調用)跳轉後返回

四:協處理器

格式:
這裏寫圖片描述

mrc p15 ,0 ,r0 ,c1 ,c0,0 @把cp15協處理器裏面 的c1值讀到cpu寄存器r0
bic r0,r0 #0x00002000
.
.
.
mcr p15,0,r0,c1,c0,0 @把cpu寄存器r0裏面的值寫到cp15協處理器c1裏面

如何看懂以上指令作用?
可百度查到相應寄存器的功能表,每一個bit位置爲不同數,表示不同的實現功能。會看懂即可,沒必要深究
這裏寫圖片描述

五:多寄存器訪問指令

ldr/str每週期只能訪問4字節內存,如果需要批量讀取、寫入內存時太慢,解決方案是stm/ldm

ldm(load register mutiple)
stm(store register mutiple

舉例:

stmia   sp, {r0 - r12}

@將r0存入sp指向的內存處(假設爲0x30001000);然後地址+4(即指向0x30001004),將r1存入該地址;然後地址再+4(指向0x30001008),將r2存入該地址······直到r12內容放入(0x3001030),指令完成。
一個訪存週期同時完成13個寄存器的讀寫

8種後綴:

ia(increase after)先傳輸,再地址+4
ib(increase before)先地址+4,再傳輸
da(decrease after)先傳輸,再地址-4
db(decrease before)先地址-4,再傳輸
fd(full decrease)滿遞減堆棧
ed(empty decrease)空遞減堆棧
fa(·······) 滿遞增堆棧
ea(·······)空遞增堆棧

ia對應空增棧
ib對應滿增棧
da對應空減棧
db對應滿減棧

最常見的是stmia和stmfd

四種棧

空棧:棧指針指向空位,每次存入時可以直接存入然後棧指針移動一格;而取出時需要先移動一格才能取出
滿棧:棧指針指向棧中最後一格數據,每次存入時需要先移動棧指針一格再存入;取出時可以直接取出,然後再移動棧指針
增棧:棧指針移動時向地址增加的方向移動的棧
減棧:棧指針移動時向地址減小的方向移動的棧

謹記:操作棧時使用相同的後綴就不會出錯,不管是滿棧還是空棧、增棧還是減棧

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