[ARM] ARM指令集

ARM指令集

 

1、ARM指令的格式和分類

經典ARM指令格式以下:性能

<opcode>    {<cond>}    {S}    <Rd>,<Rn>,<operand2>
 
  • <> 爲必選項,{}爲可選項
  • 爲操做碼,如ADD表示算術加操做指令
  • {} 決定指令執行條件域
  • {S} 決定指令執行是否影響CPSR寄存器的值
  • 爲目的寄存器
  • 的第一個操做數爲寄存器
  • 爲第二個操做數
 

2、ARM指令條件執行及標誌位

  • ARM指令能夠經過添加適當的條件碼後綴來達到條件執行的目的
    這樣能夠提升代碼密度,減小分支跳轉指令數目,提升性能。
    測試

  • 默認狀況下,數據處理指令不影響條件碼標誌位,但能夠選擇經過添加「S」來影響標誌位
    CMP不須要增長 「S」就可改變相應的標誌位。
    spa

  • 使用條件碼能夠實現高效的邏輯操做,節省跳轉和條件語句,提升代碼效率
    若是指令不標明條件碼,將默認爲無條件(AL)執行。
    code

  • 條件碼錶
    blog

 

3、跳轉指令

  跳轉指令用於實現程序流程的跳轉,在ARM程序中有兩種方法能夠實現程序的跳轉,一種是使用跳轉指令直接跳轉,另外一種是直接向PC寄存器賦值實現跳轉。進程

  • B{條件} 目標地址
      B指令最簡單的跳轉指令,一旦遇到一個B指令,ARM處理器當即跳轉至給定的目標地址,由此處繼續執行。跳轉指令B限制在當前指令的土32MB範圍內ip

  • BL{條件} 目標地址
      BL是一另個跳轉指令,在跳轉前會將下一條指令的地址複製到R14中,而後跳轉到指定的地址運行程序。能夠經過將R14的內容從新加載到PC中,並返回到跳轉指令以後的那個指令處執行。 BL是實現子程序調用的一個基本但經常使用的手段。內存

  • BLX{條件} 目標地址
      BLX指令從ARM指令集跳轉到指令中所指定的目標地址,並將處理器的工做狀態由ARM狀態切換到Thumb狀態,該指令同時將PC的當前內容到寄存器R14中。當程序使用Thumb指令集,而調用者使用ARM指令集時,能夠經過BLX指令實現程序的調用和處理器工做狀態的切換。子程序的返回能夠經過將寄存器R14複製到PC中來完成。it

  • BX{條件} 目標地址
      BX指令是帶狀態切換的跳轉指令,跳轉到指定的目標地址執行程序。若目標地址寄存器的[0]位爲1,則跳轉時自動將CPSR中的標誌T置位,即把目標地址的代碼解釋爲Thumb指令。若目標地址寄存器的[0]位爲0,則跳轉時自動將CPSR中的標誌T復位,即把目標地址的代碼解釋爲ARM指令。io

 

4、數據處理指令

  • MOV{條件} {S} 目的寄存器,源操做數
    MOV指令能夠完成的功能包括:
    • 數據從一個寄存器到另外一個寄存器的傳輸
    • 將常數傳送到寄存器中
    • 實現移位操做,左移位能夠實現將操做數乘以2^n
    • 當PC寄存器做爲目標寄存器時能夠實現程序的跳轉
    • 當PC寄存器做爲目標寄存器且指令中S位被設置時,指令在執行跳轉操做的同時,將當前處理器模式的處理器模式的SPSR寄存器內容複製到CPSR中
MOV    R0,R1
MOVS   R1,R3,LSL,#3
MOV    PC,LR

 

  • MVN{條件} {} 目的寄存器,源操做數
      MVN指令可完成從另外一個寄存器、被移位的寄存器或將一個當即數加載到目的寄存器。與MOV指令不一樣之處是在傳送以前按位被取反了,即把一個被取反的值傳送到目的寄存器中。其中S決定指令的操做是否影響CPSR中條件標誌位的值,當沒有S時指令不更新CPSR中條件標誌位的值。由於其具備取反功能,因此能夠裝載範圍更廣的當即數。
MVN    R1,#0xFF
MVN    R1,R2
MVN    R0,#0

 

 

  • ADD{條件} {S} 目的寄存器,操做數1,操做數2
      ADD指令用於把兩個操做數相加,並將結果存放到目的寄存器中,同時根據操做的結果更新CPSR中相應的條件標誌位
ADDS   R1,R1,#1
ADD    R1,R1,R2
ADD    R0,R2,R3,LSL,#1

 
  • SUB{條件} {S} 目的寄存器,操做數1,操做數2
      SUB指令用於把操做數1減去操做數2,並將結果存放在目的寄存器中,同時根據操做的結果更新CPSR中相應的條件標誌位。該指令可用於有符號數或無符號數據減法運算。
SUB     R0,R0,#1
SUBS   R0,R1,R2
SUB     R0,R2,R3,LSL,#1

 
  • RSB{條件} {S} 目的寄存器,操做數1,操做數2
      RSB指令稱爲逆向減法指令,用於把操做數2,減去操做數1,並將結果存放到目的寄存器中,同時根據操做的結果更新CPSP中相應的條件標誌位。該指令可用於有符號數或無符號數據減法運算。
RSB    R3,R1,#0xFF00
RSB    R0,R2,R3,LSL,#1
RSB    R0,R1,#0 

 
  • ADC{條件} {S} 目的寄存器,操做數1,操做數2
      ADC指令用於把兩個操做數相加,再加上CPSR中的C條件標誌位的值,並將結果存放到目的寄存器中。同時根據操做的結果更新CPSR中相應的條件標誌位。它使用一個進位標誌位,這樣就能夠作比32位大的數據加法,注意不要忘記S後綴來更改進位標誌。操做數1應是一個寄存器,操做數2能夠是寄存器、被移位的寄存器或一個當即數。
ADDS   R0,R0,R2
ADC     R1,R2,R3

 
  • SBC{條件} {S} 目的寄存器,操做數1,操做數2
      SBC指令用於把操做數1減去操做數2,再減去CPSR中的C條件標誌位的反碼,而後將結點存放到目的寄存器中。同時根據操做的結果更新CPSR中相應的條件標誌位。該指令使用進位標誌來表示借位,這樣就能夠作大於32位的減法。注意不要忘記設置S後綴來更改進位標誌,該指令可用於有符號數或無符號數據減法運算。
SUBS  R0,R0,R2
SUB   R1,R1,R3

 
  • RSC{條件} {S} 目的寄存器,操做數1,操做數2
      RSC指令用於把操做數2減去操做數1,再減去CPSR中的C條件標誌位的反碼,並將結果存放到目的寄存器中。同時根據操做的結果更新CPSR中相應的條件標誌位。該指令使用進位標誌來表示借位,這樣就能夠作大於32位的減法。注意不要忘記設置S後綴來更改進位標誌,該指令可用於有符號數或無符號數據減法運算。
RSBS   R2,R0,#0
RSC    R3,R1,#0
RSC    R0,R1,R2

 
  • AND{條件} {S} 目的寄存器,操做數1,操做數2
      AND指令用在兩個操做數上進行邏輯與運算,並把結果存放到目的寄存器中。同時根據操做的結果更新CPSR中相應的條件標誌位,該指令學用於屏蔽操做數1的某些位。
AND   R0,R0,#3
AND   R2,R1,R3

 
  • ORR{條件} {S} 目的寄存器,操做數1,操做數2
      ORR指令用在兩個操做數上進行邏輯或運算,並把結果旋轉到目的寄存器中。同時根據操做的結果更新CPSR中相應的條件標誌位,該指令經常使用於設置操做數1的的某些位。
ORR     R0,R0,#3
MOV    R1,R2,LSR,#4
ORR     R3,R1,R3,LSL,#4

 
  • EOR{條件} {S} 目的寄存器,操做數1,操做數2
      EOR指令用在兩個操做數上進行邏輯異或運算,並把結果放置到目的寄存器中。同時根據操做的結果更新CPSR中相應的條件標誌位,該指令經常使用於反轉操做數1的某些位。
EOR    R1,R1,#0x0F
EOR    R2,R1,R0
EORS   R0,R5,#0x01

 
  • BIC{條件} {S} 目的寄存器,操做數1,操做數2
      BIC指令用於清除操做數1的某些位,並把結果放置到目的寄存器中。同時根據操做的結果更新CPSR中相應的條件標誌位。操做數2爲32位的掩碼,若是在掩碼中設置了某一位,則清除這一位,未設置掩碼位保持不變。
BIC    R0,R0,#%1011
BIC    R1,R1,#0x0F
BIC    R1,R2,R3

 
  • CMP{條件} 操做數1,操做數2
      CMP指令用於把一個寄存器的內容和另外一個寄存器的內容或當即數進行比較,同時更新CPSR中的條件標誌位的值。該指令進行一次減法運算,但不存儲結果,只更改條件標誌位,標誌位表示的是操做數1與操做數2的關係。若是操做數1大於操做數2,則此後GT後綴的指令將執行,不需顯示的指定S後綴更改狀態標誌,若是指定了則忽略。

  • CMN{條件} 操做數1,操做數2
      CMN指令用於把一個寄存器的內容和另外一個寄存器的內容或當即數據取反後進行比較。同時更新CPSR中條件標誌位的值,該指令實際完成操做數1和操做數2相加,並根據結果更改條件標誌位。CMN指令與ADD指令的區別在於CMN指令不保存運算結果。

CMN    R1,R0
CMN    R1,#100

 
  • TST{條件} 操做數1,操做數2
      TST指令用於把操做數1的內容和操做數的內容進行按位與運算,並根據運算結果更新CPSR中條件標誌位的值。操做數1是要測試的數據,而操做數2是一個位掩碼,該指令通常用來檢測是否設置了特定的位。
TST    R0,#0x01
TST    R0,#0x0F    

 
  • TEQ{條件} 操做數1,操做數2
      TEQ指令用於把操做數1的內容和操做數的內容進行按位異或運算,並根據運算結果更新CPSR中條件標誌位的值。該指令一般用於比較操做數1和操做數2是否相等。
TEQ    R1,R2
 

 

5、程序狀態寄存器傳輸指令

  ARM指令有兩條指令用於狀態寄存器和通用寄存器之間傳送數。修改寄存器通常是經過 「讀取-修改-寫回」 三個步驟的操做來實現的。這兩指令分別是狀態寄存器到通用寄存器的傳送指令MRS,通用寄存器到狀態寄存器的傳送指令MSR。

  • MRS{條件} 通用寄存器,程序狀態寄存器
      當異常中斷容許被嵌套時,須要在進入異常中斷後嵌套中斷髮生以前的保存當前處理器對應的SPSR。在進程切換時也須要保存當前狀態寄存器的值。
MRS    R0,CPSR
MRS    R0,SPSR

 
  • MSR{條件} 程序狀態寄存器_<域>,通用寄存器
      當退出異常中斷處理程序時,若是事先有保存狀態寄存器的內容,一般使用MSR將事先保存的數據恢復到狀態寄存器中。域用於設置程序狀態寄存器中須要操做的位,32位的程序狀態寄存器可分爲4個域:
    • [31:24] 爲條件標誌位域,用f表示
    • [23:16] 爲狀態位域,用s表示
    • [15:8] 爲擴展位域,用x表示
    • [7:0] 爲控制位域,用c表示
MSR   CPSR_c,#0xD3
MSR   CPSR_cxsf,R3
 

 

6、Load與Store指令

  Load指令用於從內存中讀取數據放入寄存器中,Store指令用於將寄存器中的數據保存到內存。

  • LDR{條件} 目的寄存器,<存儲器地址>
      LDR指令用於從存儲器中將一個32位的數據傳送到目的寄存器中。當程序計數器PC做爲目的寄存器時,指令從存儲器中讀取的數據被目的地址,從而實現程序流程的跳轉。
LDR    R0,#8
LDR    R0,[R1,R2]
LDR    R0,[R1, 8] 

 
  • STR{條件} 源寄存器,<存儲器地址>
    STR指令用於從源寄存器中將一個32位數據傳送到存儲器中。
STR    #8,R0
STR    R0,[R1,#8]    

 
  • LDM/STM{條件} {類型} 基址寄存器,寄存器列表
      LDM和STM能夠實如今一組寄存器和一塊連續的內存單元之間傳輸數據。LDM爲加載多個寄存器,STM爲存儲多個寄存器。LDM、STM的主要用途是現場保存,數據複製,參數傳遞,其模式有8種:
    • 用於數據塊傳輸
      IA 每次傳送後地址加4
      IB 每次傳送前地址加4
      DA 每次傳送後地址減4
      DB 每次傳送前地址減4
    • 用於堆棧操做
      FD 滿遞減堆棧
      ED 空遞減堆棧
      FA 滿遞增堆棧
      EA 空遞增堆棧
STMFD    R13,{R0,R4-R12,LR}
DMFD    R13,{R0,R4-R12,LR}

 
  • SWP {條件} 目的寄存器,源寄存器1,[源寄存器2]
      SWP指令用於將源寄存器2中的把指向的存儲器中的數據傳送到目的寄存器中。同時將源寄存器1中的數據傳送到源寄存器2所指向的存儲器中。當源寄存器1和目的寄存器爲同一寄存器時,指令將交換目的寄存器和存儲器的內容。

 

七、異常中斷產生指令

SWI,即software interrupt軟件中斷。該指令產生一個SWI異常。意思就是處理器模式改變爲超級用戶模式,CPSR寄器保存到超級用戶模式下的SPSR寄存器,而且跳轉到SWI向量。

  指令格式以下:SWI{cond} immed_24
  Cond域:是可選的條件碼 (參見 ARM彙編指令條件執行詳解).
  immed_24域:範圍從 0 到 224-1 的表達式, (即0-16777215)。用戶程序可使用該常數來進入不一樣的處理流程。

相關文章
相關標籤/搜索