一、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>
- cond:指令執行的條件碼,如果忽略的話就表示無條件執行 ;
- opc1:協處理器要執行的操作碼 ;
- Rt: ARM 源寄存器,要寫入到 CP15 寄存器的數據就保存在此寄存器中 ;
- CRn: CP15 協處理器的目標寄存器;
- CRm: 協處理器中附加的目標寄存器或者源操作數寄存器,如果不需要附加信息就將;
CRm 設置為 C0,否則結果不可預測; - 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模式 */
