部分ARM匯編指令解讀


一、LDR(Load Register  加載寄存器)將存儲器地址所指地址處連續的4個字節(1個字)的數據傳送到目的寄存器中(pseudo-instruction loads a register with a 32-bit immediate value or an
address)。

  例:

1 /* 將Reset_Handler函數的地址加載到pc寄存器中 */
2 ldr pc, =Reset_Handler
3 /* 將Reset_Handler函數的地址加載到r0寄存器中*/
4 ldr r0, =Reset_Handler

二、BX(Branch and Exchange 分支和交換)指令跳轉到指令中所指定的目標地址,若目標地址的bit[0]為0,則跳轉時自動將CPSR中的標志位T復位,即把目標地址的代碼解釋為ARM代碼;若目標地址的bit[0]為1,則跳轉時自動將CPSR中的標志位T置位,即把目標地址的代碼解釋為Thumb代碼。

  例:

1 /* 以下指令的作用是在函數Reset_Handler中一直循環 */
2 Reset_Handler:
3   ldr r0, =Reset_Handler
4   bx r0

三、MRC讀CP15(C0-C15)寄存器

  MRC{cond} p15, <opc1>, <Rt>, <CRn>, <CRm>, <opc2> 

  1. cond:指令執行的條件碼,如果忽略的話就表示無條件執行 ;
  2. opc1:協處理器要執行的操作碼 ;
  3. RtARM 源寄存器,要寫入到 CP15 寄存器的數據就保存在此寄存器中 ;
  4. CRnCP15 協處理器的目標寄存器;
  5. CRm: 協處理器中附加的目標寄存器或者源操作數寄存器,如果不需要附加信息就將;
    CRm 設置為 C0,否則結果不可預測;
  6. opc2: 可選的協處理器特定操作碼,當不需要的時候要設置為 0 。

例:

MRC p15, 0, r0, c0, c0, 0 ;將 CP15 中 C0 寄存器的值讀取到 R0 寄存器中

四、MCR寫CP15(C0-C15)寄存器

  MCR{cond} p15, <opc1>, <Rt>, <CRn>, <CRm>, <opc2> 

  同上。

例:

ldr r0, =0X87800000     ; r0=0X87800000 
MCR p15, 0, r0, c12, c0, 0 ;將 r0 里面的數據寫入到 c12 中,即 c12=0X87800000 

五、 ADD(add 加)不帶進位的加法指令,指令完成目的操作數與源操作數相加,將結果存回目標操作數。

例:

MRC p15, 4, r1, c15, c0, 0   ;獲取 GIC 基地址 
ADD r1, r1, #0X2000       ;GIC 基地址加 0X2000 得到 CPU 接口端寄存器起始地址 
LDR r0, [r1, #0XC]        ;讀取 CPU 接口端起始地址+0XC 處的寄存器值,也就是寄存器     
                  ;GIC_IAR 的值

 六、CPSID(禁止IRQ中斷)和CPSIE(打開IRQ中斷)

  Syntax

  CPSIE iflags{, #mode}
  CPSID iflags{, #mode}

  where

  IE Interrupt or Abort Enable.

  ID Interrupt or Abort Disable.

  iflags specifies one or more of:
  • a = asynchronous abort.
  • i = IRQ.
  • f = FIQ. 

例:

cpsid i  ;禁止IRQ中斷
cpsie i  ; 打開IRQ中斷

 

 七、BIC(位清除)可以用來清除寄存器的指定位

例:

1 mrc p15, 0, r0, c1, c0, 0     /* 讀取CP15的C1寄存器到R0中            */
2 bic r0, r0, #(0x1 << 12)      /* 清除C1寄存器的bit12位(I位),關閉I Cache   */
3 bic r0, r0, #(0x1 <<  2)      /* 清除C1寄存器的bit2(C位),關閉D Cache     */
4 bic r0, r0, #0x2              /* 清除C1寄存器的bit1(A位),關閉對齊        */
5 bic r0, r0, #(0x1 << 11)      /* 清除C1寄存器的bit11(Z位),關閉分支預測    */
6 bic r0, r0, #0x1              /* 清除C1寄存器的bit0(M位),關閉MMU        */
7 mcr p15, 0, r0, c1, c0, 0     /* 將r0寄存器中的值寫入到CP15的C1寄存器中    */

 

 

 八、DSB(數據同步隔離)、ISB(指令同步隔離)和DMB(數據存儲器隔離)

  DSB: 僅當所有在它前面的存儲器訪問操作都執行完畢后,才執行在它后面的指令;

  ISB:它會清洗流水線,以保證所有它前面的指令都執行完畢后,才執行它后面的指令;

  DMB:僅當所有在它前面的存儲器訪問操作都執行完畢后,才提交(commit)在它后面的存儲器訪問操作。

 例:

    ldr r0, =0X87800000
    dsb
    isb
    mcr p15, 0, r0, c12, c0, 0      /* 將0x87800000地址寫到c12寄存器中 */
    dsb
    isb

 

 九、MRS(狀態寄存器傳送至通用寄存器傳送指令)和MSR(通用寄存器傳送至狀態寄存器傳送指令)

  MRS:將狀態寄存器的內容傳送至通用寄存器;

  MSR:將通用寄存器的內容傳送至狀態寄存器;

例:

    /* 進入IRQ模式 */
    mrs r0, cpsr                    /* 將cpsr中的內容寫到r0寄存器中 */
    bic r0, r0, #0x1F               /* 將r0寄存器中的低5位清零,也就是cpsr的M0-M4 */ 
    orr r0, r0, #0x12               /* r0或上0x12,表示使用IRQ模式 */
    msr cpsr, r0                    /* 將r0的數據寫入到cpsr中 */
    ldr sp, =0x80600000             /* 設置SYS模式下的棧首地址為0x80600000 */

 

十、PUSH入棧和POP出棧,遵循先進后出原,則即FILO

例:

 1    push {lr}                    /* 保存lr寄存器 */
 2    push {r0-r3, r12}            /* 保存r0-r3,r12寄存器 */
 3 
 4    mrs r0, spsr                 /* 讀spsr寄存器 */
 5    push {r0}                    /* 保存spsr寄存器 */
 6 
 7    mrc p15, 4, r1, c15, c0, 0   /* 將CP15的C0內的值保存到R1寄存器中 */
 8 
 9    add r1, r1, #0x2000          /* GIC基地址加0x2000,得到CPU接口端基地址 */
10    ldr r0, [r1, #0xC]           /* CPU接口端基地址加0x0C就是GICC_IAR寄存器 */
11                                 /* GICC_IAR保存着當前發生中斷的中斷號 */
12 
13     push {r0, r1}               /* 保存r0和r1 */
14 
15     cps #0x13                   /* 進入SVC模式,允許其他中斷再次進去 */
16 
17     push {lr}                   /* 保存SVC模式的lr寄存器 */
18     ldr r2, =system_irqhandler  /* 加載c語言中斷處理函數到r2寄存器中 */
19     blx r2                      /* 運行c語言中斷處理函數,帶有一個參數 */
20     pop {lr}                    /* 執行完c語言中斷服務函數,lr出棧 */
21 
22     cps #0x12                   /* 進入IRQ模式 */
23 
24     pop {r0, r1}
25 
26     str r0, [r1, #0x10]         /* 中斷執行完成,寫EOIR */
27 
28     pop {r0}
29     msr spsr_cxsf, r0           /* 恢復spsr */
30 
31     pop {r0-r3, r12}            /* r0-r3,r12除棧 */
32     pop {lr}                    /* lr出棧 */
33     subs pc, lr, #4             /* 將lr-4賦給pc */

 

 十一、CPS(Change Processor Status 改變處理器狀態)用於改變處理器的狀態或者是使能、禁用單獨的異常類型(Can be used to change the processor mode or to enable or disable
individual exception types)。

  Syntax
  CPS #mode
  where:
  mode is the number of a mode for the processor to enter.

例:

1 cps #0x12                   /* 進入IRQ模式 */

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM