1. 程式人生 > >ARM-彙編指令集(總結)

ARM-彙編指令集(總結)

https://www.cnblogs.com/wxb20/p/6249580.html
ARM彙編指令集

指令、偽指令

(彙編)指令: 是機器碼的助記符,經過彙編器編譯後,由CPU執行。

(彙編)偽指令:用來指導指令執行,是彙編器的產物,最終不會生成機器碼。

有兩種不同風格的ARM指令

1).ARM官方的ARM彙編風格:指令一般用大寫,Windows中的IDE開發環境。

2).GNU風格的ARM彙編:指令一般用小寫。

ARM彙編的特點

  1. LDR/STR架構

1).ARM採用RISC架構,CPU本身不能直接讀取記憶體,而需要先將記憶體中內容載入入CPU中通用暫存器中才能被CPU處理。
2).ldr(load register)指令將記憶體內容載入入通用暫存器。
3).str(store register)指令將暫存器內容存入記憶體空間中。
4).ldr/str組合用來實現 ARM CPU和記憶體資料交換。

  1. 至此8種定址方式

1).暫存器定址mov r1, r2。
2).立即(立即數)定址 mov r0, #0xFF00。
3).暫存器移位定址 mov r0, r1, lsl #3。
4).暫存器間接定址 ldr r1, [r2] 表示記憶體,記憶體地址存在r2這個暫存器中,把記憶體地址裡的值給r1。
5).基址變址定址ldr r1, [r2, #4]記憶體地址在r2+4裡面。
6).多暫存器定址 ldmia r1!, {r2-r7, r12}一次訪問多個暫存器。
7).堆疊定址 stmfd sp!, {r2-r7, lr}。
8).相對定址 beq flag。

  1. 指令字尾

同一指令經常附帶不同字尾,變成不同的指令。經常使用的字尾有:
B(byte)功能不變,操作長度變為8位
H(half word)功能不變,長度變為16位
S(signed)功能不變,運算元變為有符號
如 ldr ldrb ldrh ldrsb ldrsh
S(S標誌)功能不變,影響CPSR標誌位
如 mov和movs movs r0, #0

  1. 條件執行字尾

條件字尾是否成立取決於當前程式碼的前面的程式碼。

條件字尾隻影響當前程式碼的執行。

  1. 多級指令流水線

為增加處理器指令流的速度,ARM使用多級流水線.,下圖為3級流水線工作原理示意圖。(S5PV210使用13級流水線,ARM11為8級)
允許多個操作同時處理,而非順序執行。

1).PC指向正被取指的指令,而非正在執行的指令

資料傳輸與跳轉指令詳解

  1. 資料處理指令
    資料傳輸指令 mov mvn
    算術指令 add sub rsb adc sbc rsc
    邏輯指令 and orr eor bic
    比較指令 cmp cmn tst teq
    乘法指令 mvl mla umull umlal smull smlal
    前導零計數 clz

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

  3. 跳轉(分支)指令
    b & bl & bx
    b 直接跳轉(就沒開啟算返回)
    bl branch and link,跳轉前把返回地址放入lr中,以便返回,以便用於函式呼叫
    bx跳轉同時切換到ARM模式,一般用於異常處理的跳轉。

  4. 訪存指令

ldr/str & ldm/stm & swp
單個字/半字/位元組訪問 ldr/str
多字批量訪問 ldm/stm

swp r1, r2, [r0]
swp r1, r1, [r0]

  1. 軟中斷指令

swi(software interrupt)
軟中斷指令用來實現OS中系統呼叫

ARM彙編中的立即數

合法立即數與非法立即數
ARM指令都是32位,除了指令標記和操作標記外,本身只能附帶很少位數的立即數。因此立即數有合法和非法之分。
合法立即數:經過任意位數的移位後非零部分可以用8位表示的即為合法立即數。

協處理器與協處理器指令集

6.協處理器cp15操作指令
mcr & mrc
mrc用於讀取CP15中的暫存器
mcr用於寫入CP15中的暫存器

7.arm定址方式

1). 暫存器: MOV R1,R2 ; R2->R1
2). 立即數: SUBS R0,R1,#1; R0=R1-1
3). 暫存器移位:MOV R0,R2,LSL #3 ;R2左移三位->R0
4). 間接定址: LDR R1,[R2] ; 裝載R2指向的記憶體數值至R1
5). 基址定址: LDR R2,[R3,#0x0F] ;R3+0x0F作為地址,將所指向的置裝入R2.R3的值不改變
6). 多暫存器定址: LDMIA R1!,{R2-R7,R12} ; 將R1所指向的記憶體塊依次裝入{}中的暫存器。
STMIA R0!,{R3-R6,R10} ;將{}列出的暫存器裡的值依次填入R0所指向的記憶體塊。
7). 相對定址: BL XXX ;跳轉
BEQ XXX ;條件跳轉

協處理器解析:
SoC內部另一處理核心,協助主CPU實現某些功能,被主CPU呼叫執行一定任務。
ARM設計上支援多達16個協處理器,但是一般SoC只實現其中的CP15.(cp:coprocessor)
協處理器和MMU、cache、TLB等處理有關,功能上和作業系統的虛擬地址對映、cache管理等有關。

MRC & MCR的使用方法
mcr{} p15, <opcode_1>, , , , {<opcode_2>}
opcode_1:對於cp15永遠為0
Rd:ARM的普通暫存器
Crn:cp15的暫存器,合法值是c0~c15
Crm:cp15的暫存器,一般均設為c0
opcode_2:一般省略或為。

ldm/stm與棧的處理

為什麼需要多暫存器訪問指令
ldr/str每週期只能訪問4位元組記憶體,如果需要批量讀取、寫入記憶體時太慢,解決方案是stm/ldm
ldm(load register mutiple)
stm(store register mutiple)
舉例(uboot start.S 537行)
stmia sp, {r0 - r12}
將r0存入sp指向的記憶體處(假設為0x30001000);然後地址+4(即指向0x30001004),將r1存入該地址;然後地址再+4(指向0x30001008),將r2存入該地址······直到r12內容放入(0x3001030),指令完成。
一個訪存週期同時完成13個暫存器的讀寫

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

四種棧解析:
空棧:棧指標指向空位,每次存入時可以直接存入然後棧指標移動一格;而取出時需要先移動一格才能取出。
滿棧:棧指標指向棧中最後一格資料,每次存入時需要先移動棧指標一格再存入;取出時可以直接取出,然後再移動棧指標。
增棧:棧指標移動時向地址增加的方向移動的棧。
減棧:棧指標移動時向地址減小的方向移動的棧。

!的作用:
ldmia r0, {r2 - r3}
ldmia r0!, {r2 - r3}

感嘆號的作用就是r0的值在ldm過程中發生的增加或者減少最後寫回到r0去,也就是說ldm時會改變r0的值。

^的作用:
ldmfd sp!, {r0 - r6, pc}
ldmfd sp!, {r0 - r6, pc}^

^的作用:在目標暫存器中有pc時,會同時將spsr寫入到cpsr,一般用於從異常模式返回。

總結:批量讀取或寫入記憶體時要用ldm/stm指令。
各種字尾以理解為主,不需記憶,最常見的是stmia和stmfd。
謹記:操作棧時使用相同的字尾就不會出錯,不管是滿棧還是空棧、增棧還是減棧。

常用gun偽指令:
global _start @ 給_start外部連結屬性
.section .text @ 指定當前段為程式碼段
.ascii .byte .short .long .word .quad .float .string @ 定義資料
.align 4 @ 以2*4位元組對齊
.balignl 16 0xabcdefgh @ 16位元組對齊填充
.equ @ 類似於C中巨集定義

偶爾會用到的gun偽指令
.end @標識檔案結束
.include @ 標頭檔案包含
.arm / .code32 @宣告以下為arm指令
.thumb / .code16 @宣告以下為thubm指令

重要的幾個偽指令
ldr 大範圍的地址載入指令
adr 小範圍的地址載入指令
adrl 中等範圍的地址載入指令
nop 空操作
ARM中有一個ldr指令,還有一個ldr偽指令
一般都使用ldr偽指令而不用ldr指令

adr與ldr
adr編譯時會被1條sub或add指令替代,而ldr編譯時會被一條mov指令替代或者文字池方式處理;
adr總是以PC為基準來表示地址,因此指令本身和執行地址有關,可以用來檢測程式當前的執行地址在哪裡
ldr載入的地址和連結時給定的地址有關,由連結指令碼決定。

@筆記記得有點不清晰,希望在學習ARM在座的各位指出哪有錯,大家一起進步,共同學習。@

/******************************** Stay hungry, Stay foolish. @Rocky ********************************/