1. 程式人生 > 其它 >ARM體系結構與介面技術——ARM指令集

ARM體系結構與介面技術——ARM指令集

ARM彙編框架

xx.s

.text        @表示當前為程式碼段
.global _start        @將_start定義成全域性符號
_start:        @彙編的入口

    MOV R1,#1
    MOV R2,#2
    MOV R3,#3

.end        @彙編的結束

ARM彙編概述

彙編中的符號

  1. 指令:能夠編譯成一條32位的機器碼,並且能被CPU識別和執行。
  2. 偽指令:本身不是指令,編譯器可以將其替換成若干條指令
  3. 不會生成指令,只是在編譯階段告訴編譯器怎麼編譯,類似C語言的條件編譯

ARM的指令

  1. 資料處理指令:進行數學運算、邏輯運算
  2. 跳轉指令:實現程式的跳轉,本質就是修改PC暫存器
  3. Load/Store指令:訪問(讀寫)記憶體
  4. 狀態暫存器傳送指令:用於訪問(讀寫)CPSR暫存器
  5. 軟中斷指令:觸發軟中斷
  6. 協處理器指令:操作協處理器的指令

指令基本格式

  <操作碼> <目標暫存器>, <第一操作暫存器>, <第二運算元>


 

ARM指令集

資料處理指令
.text
.global _start
_start:

    @ 資料搬運指令
    MOV R1,#1        @把一個數搬運到一個暫存器
    MOV R2,R1        @從一個暫存器搬運到另一個暫存器
    MVN R0,#0xFF    @按位取反再搬運
    
    @ 
MOV PC,#0 @搬運一個數到PC暫存器,程式會跳轉 @ 立即數,本質是包含在指令中的數,屬於指令的一部分 @ 所以立即數不能太大,範圍在0-255之間。 @ MOV R0, #0x12345678 @0x12345678這不是立即數,不能被編譯成功 @ 0xFFFFFFFF這不是立即數,但是能被編譯成功 @ 這一條是偽指令,編譯器會把他替換成同樣效果的指令。 MOV R0, #0xFFFFFFFF @ MVN R0,#0x00 @ 加法指令 ADD R3,R1,R2 @ R3 = R1 + R2
ADD R3,R2,#5 @ R3 = R2 + 5 @ 不合法的指令 @ ADD R3,#5,R2 @第一暫存器不能放數 @ 減法指令 SUB R1,R2,R3 @ R1 = R2 - R3 RSB R1,R2,#3 @ R1 = 3 - R2 逆向減法指令 @ 乘法指令 MUL R1,R2,R3 @ R1 = R2 * R3 @ 按位與 AND R1,R2,R3 @ R1 = R2 & R3 @ 按位或 ORR R1,R2,R3 @ R1 = R2 | R3 @ 按位異或 EOR R1,R2,R3 @ R1 = R2 ^ R3 @ 移位 LSL R1,R2,R3 @ R1 = R2 << R3, R2左移R3位,給R1 LSR R1,R2,R3 @ R1 = R2 >> R3, R2右移R3位,給R1 @ 位清零 BIC R1, R2, #0xF @ 第二運算元(0xF)中的哪一位,就將第一操作暫存器中的哪一位清零,然後放入目標暫存器 @ 資料運算指令的格式擴充套件 MOV R1,R2,LSL #1 @ R1 = (R2 << 1) @ 資料運算指令對條件位的影響,CPSR NZVC @ 預設情況下資料運算不會對條件為產生影響,當指令加字尾S後可以影響 MOV R1,#3 SUBS R2,R1,#5 @ 兩個64位的資料做加法運算 @ 0x00000001 FFFFFFFF @ 0x00000002 00000005 MOV R1,#0xFFFFFFFF MOV R2,#0x00000001 MOV R3,#0x00000005 MOV R4,#0x00000002 ADDS R5,R1,R3 @溢位時條件位溢位位會自動置1 ADC R6,R2,R4 @ R6 = R2 + R4 + 'C',在執行的過程中,會把條件位的溢位位加上 @ 帶借位的減法指令 @ 0x00000002 00000001 @ 0x00000001 00000005 MOV R1,#0x00000001 MOV R2,#0x00000002 MOV R3,#0x00000005 MOV R4,#0x00000001 SUBS R5,R1,R3 SBC R6,R2,R4 @ 本質: R6 = R2 - R4 - '!C',即執行的過程中,會把條件位的溢位位取反再減 stop: B stop .end


 

跳轉指令
.text
.global _start
_start:

    
    @ 方式一:直接去修改PC暫存器的值
    @ MOV R1,#1
    @ MOV R2,#2
    @ MOV R3,#3
    @ MOV PC,#0x18
    @ MOV R4,#4        @ 這條指令被跳過
    
    @ MOV R6,#6
    
    
    @ 方式二:通過跳轉指令B
    @ 本質也是修改PC
    @ MOV PC,LR 跳轉失敗,它會跳轉回:跳轉指令,因為B跳轉指令,沒有儲存返回地址給LR
@MAIN:
@    MOV R1,#1
@    B FUNC
@    MOV R2,#2
@    MOV R3,#3
@FUNC:
@    MOV R4,#4
@    MOV PC,LR
    
    @ 方式三:通過跳轉指令BL
    @ 跳轉的同時,會修改CPSR的跳轉狀態位的值,並且儲存返回的地址給LR
MAIN:
    MOV R1,#1
    MOV R2,#2
    BL FUNC
    MOV R3,#3
    MOV R4,#4
FUNC:
    MOV R5,#5
    MOV PC,LR
    
stop:
    B stop
.end

 

ARM條件碼(不算指令)
@條件碼
.text
.global _start
_start:

MAIN:
    MOV R1,#1
    MOV R2,#1
    
    @比較指令
    CMP R1,R2    @沒有目標暫存器,結果自動儲存在狀態暫存器CPSR的NZCV
    @本質就是一條減法指令,SUBS,只是沒有將運算的結果存入暫存器
    @如果R1==R2,Z=1,產生0
    @如果R1!=R1,Z=0
    @如果R1<R2,Z=0且C=0,產生了借位
    @如果R1<=R2,C=0或Z=1
    @如果R1>R2,C=1且Z=0
    @如果R1>=R2,C=1或Z=1
    
    BEQ FUNC    @EQ是一個條件碼助記符字尾,大多數指令都可以加字尾
    MOV R3,#3    @該條指令會被跳過
FUNC:
    MOV R4,#4    @程式會跳轉到這裡

.end

ARM條件碼和助記符字尾


ARM記憶體訪問指令

記憶體訪問指令1

@記憶體訪問指令
.text
.global _start
_start:

    @ 寫記憶體
    MOV R1,#0xFFFFFFFF
    MOV R2,#0x40000000    @0x40000000 是可讀可寫的記憶體地址
    @STR R1,[R2]        @把R1暫存器中的資料儲存到R2指向的記憶體空間4個位元組
    STRB R1,[R2]        @把R1暫存器中的資料儲存到R2指向的記憶體空間
    
    @ 讀記憶體
    LDR R3,[R2]        @把R2指向的記憶體空間的資料讀取到R3


.end

 

ARM指令的定址方式

@ ARM定址方式

.text
.global _start
_start:

    @ 方式一:立即定址
    @ 回顧一下立即數,立即定址即直接使用指令機器碼中的立即數
    MOV R1,#1
    ADD R1,R2,#1
    
    @ 方式二:暫存器取址
    ADD R1,R2,R3
    
    @ 方式三:暫存器移位定址
    MOV R1,R2, LSL #1
    
    @ 方式四:暫存器間接定址
    STR R1, [R2]
    
    @...還有很多,ARM一共九種

.end

記憶體訪問指令2

@ 記憶體訪問指令2
@ 基於ARM指令的定址方式
@ 基址加變址定址

.text
.global _start
_start:


    MOV R1, #0xFFFFFFFF
    MOV R2, #0x40000000
    MOV R3, #4
    
    @ 前索引:
    @STR R1, [R2,#4]
    @ 將R1暫存器中的資料寫入到R2+4指向的記憶體空間:0x40000004
    @ R2的值並不會改變,對比自動索引
    
    @STR R1, [R2,R3]
    @ 將R1暫存器中的資料寫入到R2+R3指向的記憶體空間:0x40000004
    
    @STR R1, [R2,R3,LSL #1]
    @ 將R1暫存器中的資料寫入到R2+(R3<<1)指向的記憶體空間:0x40000008

@*****************************************************************
    
    
    @ 後索引:
    STR R1, [R2], #8
    @ 將R1暫存器中的資料寫入到R2指向的記憶體空間:0x40000000
    @ 然後R2自增8
    
    
    @ 自動索引:
    STR R1, [R2,#8]!
    @ 將R1暫存器中的資料寫入到R2+8指向的記憶體空間:0x40000008
    @ 然後R2自增8
    

.end

 

 

 


 

END