歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> ARM匯編指令集學習筆記

ARM匯編指令集學習筆記

日期:2017/3/1 9:15:38   编辑:Linux編程

ARM匯編指令集:

指令:匯編指令是CPU機器指令的助記符,經過編譯後會得到一串1、0組成的機器碼,可以由CPU讀取執行

偽指令:在編譯過程中間起作用,用來指導編譯過程,經過編譯後不會生成機器碼

***ARM匯編特點1:LDR/STR架構:在RISC架構中,cpu讀寫內存需要通過CPU內部的寄存器(CISC的CPU可以直接和內存通信)

***ARM匯編特點2:8中尋址方式

#寄存器尋址 mov r1,r2 把r2裡面的內容送到r1裡面去(寄存器靠名字找的)

#立即尋址(立即數) mov r0,#0xFF00 加#表示數字

#寄存器移位尋址 mov r0, r1, lsl #3 lsl左移指令,把r1的值左移三位,然後把左移後生成的那個數賦值給r0

#寄存器間接尋址 ldr r1, [r2] [r2]表明內存地址存在r2中 ,然後把內存地址裡面存儲的那個值賦給r1

基址變址尋址 ldr r1, [r2, #4]
[r2,#4]中存儲的地址為r2中的地址+4構成的地址,r2裡面存儲的地址稱為基地址,後面的數字就是需要的變址數 這條指令的意思:把r2存儲的內存地址加4的地址的值賦值給r1

#多寄存器尋址 ldmia r1!, {r2-r7, r12}
一次訪問多個寄存器//////r1放的內存地址,把r1理解為數組,r2-r7,r12表示7個寄存器,
這句指令的意思就是:r1當中存儲的內存地址為基地址,然後把從這個地址開始的連續七個地址當中存儲的值,依次放在後面對應的寄存器中

#堆棧尋址 stmfd sp!, {r2-r7, lr}

#相對尋址 beq flag
flag: 標號


***ARM匯編特點3:指令後綴

同一指令經常附帶不同後綴,變成不同的指令。經常使用的後綴有:

B(byte)功能不變,操作長度變為8位

H(half word)功能不變,長度變為16位

S(signed)功能不變,操作數變為有符號
如 ldr ldrb ldrh ldrsb ldrsh

S(S標志)功能不變,影響CPSR標志位 一般用在數據傳輸指令

如 mov和movs movs r0, #0

***ARM匯編特點4:條件執行後綴


mov r0,r1 @相當於C語言的 r0 = r1
moveq r0,r1 @如果eq後綴成立,則執行本句指令,反之,則不執行

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


***ARM匯編特點5:多級指令流水線
pc指向正在被取指的指令 ,而非正在執行的指令


******數據傳輸指令
mov r1,r0 @兩個寄存器之間傳遞數據
mov r1,#12fff @把立即數賦值給目標寄存器

mvn 和 mov 用法一樣 區別是mov原封不動傳遞 ,mvn是按位取反傳遞


******邏輯指令
and 邏輯與
orr 邏輯或
eor 邏輯異或

bic 位清除指令 bic r0,r1,#0x1f 將r1中的數的bit0到bit4 (#0x1f為1的位清零)清零後賦值給r0


******比較指令
cmp
cmn 看兩個值是否互補
tst test r0,#0xf @測試r0的0~3位是不是為0
teq 測試等價
比較指令用來比較兩個寄存器中的數
比較指令不用後加S後綴就可以影響cpsr中的標志位


******常用ARM指令
cpsr訪問指令: mrs & msr

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


******跳轉指令
b & bl & bx
b: 直接跳轉

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

*******訪存指令
ldr /str / ldm / stm / swp

單個字/半字/字節訪問 : ldr/str
多字批量訪問 :ldm/stm

swp:內存和寄存器互換指令
swp r1,r2,[r0] 把r0存的地址的內容放到r1裡面去,然後把r2的內容放到r0存的地址的內存中去
swp r1,r1,[r0]

******************************
合法立即數與非法立即數

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


**************
協處理器cp15的操作指令

mcr& mrc
mrc用於讀取cp15中的寄存器
mcr用於寫入cp15中的寄存器


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

ldm/stm與棧的處理

ldm (load register mutiple)
stm (store register mutiple)
****************************************************************
!的作用:r0值在ldm過程中發生的增加或減少寫回到r0去,也就是ldm在運算過程中會改變r0中的地址值,如果沒有!,則r0中的地址值不發生變化,如果有!,則r0中的值,會發生相應的改變
ldmia r0,{r2,r3}

ldmia r0!,{r2,r3}

^的作用:在目標寄存器中有PC時,會同時將spsr寫入到cpsr(異常返回的時候)
ldmfd sp!,{r0-r6,pc}

ldmfd sp!,{r0-r6,pc}^

四種棧

空棧: 空棧就是當需要往棧中加入內容的時候,直接將內容存入棧指針所指向的地址空間,然後在將棧指針指向下一個空的地址空間,而要取出內容時則需要先移動指針才能去除

滿棧: 滿棧就是棧指針始終指向棧的最後一格,每次需要存儲內容時,都需要先移動棧指針,然後把你內容存入棧指針所指向的地址空間,當要取出內容的時候不用移動指針直接可以取出

增棧 棧指針移動的時候,往地址值增加的方向移動

減棧 棧指針移動的時候,往地址值減小的方向移動

**********************************************************
偽指令
@用來做注釋
#做注釋一般用來放做行首,表示這一行都是注釋而不是代碼

:以冒號結尾的是標號

.點號 在gnu匯編中表示當前指令的地址

立即數前面要加#或者$,表示這個數是立即數

Copyright © Linux教程網 All Rights Reserved