一文教你搞清楚ARM cortex-m3內核的寄存器;
1 前言
本文以ARM的Cortex-M3
內核爲例,對於ARM的內核寄存器做一個簡單的介紹,並且市面上Cortex-M3比較容易可以買到,可以結合實踐加深對ARM彙編的理解。
2 寄存器全覽
ARM的寄存器分爲通用寄存器和特殊功能寄存器,從R0
—R15
,其中,R0
-R12
都是32位通用寄存器,用於數據操作。絕大多數16位Thumb
指令只能訪問R0
-R7
,而32 位Thumb-2 指令可以訪問所有寄存器1。 具體如下圖所示;
下圖是在Keil MDK
的調試環境下的寄存器列表,如下所示;
3 SP
Stack Pointer (SP)
,棧指針寄存器,該寄存器始終保存着一個指向棧頂的值,值得注意的地方;
SP
寄存器的Bit[1:0]
(最低兩位)始終爲0
,因此這個寄存器是按照字對齊的,也就是四個字節;M3
有兩個堆棧指針,並且同一時刻只能使用其中的一個;- 主堆棧指針(
MSP/SP_main
):復位後默認使用的堆棧指針寄存器,用於操作系統內核以及異常處理例程(包括中斷服務例程); - 進程堆棧指針(
PSP/SP_process
):由用戶的應用程序代碼使用。
- 主堆棧指針(
寄存器R13
通常被用作堆棧指針寄存器,另外究竟使用哪個寄存器,由CPU
的控制寄存器來決定;
- Handler mode :即系統發生異常(中斷等)的情況會進入該模式,通常使用
SP_main
; - Thread mode:用戶程序正常運行時處於該模式,可以選擇使用
SP_main
或SP_process
;
CPU
的Configuration Control Register
,如下圖所示;
其中Bit[0]
:NONEBASETHRDENA
決定了CPU使用哪一種模式;
4 LR
Link Register (LR)
,連接寄存器,即在調用子程序的時候,可以將當前的程序地址存入LR
寄存器,這樣就方便了函數的返回;
通常LR
會配合BL
和BLX
來使用,下面簡單舉一個函數調用的例子;
BL func01
BL func02
B .
func01
MOV R5, #05
BX LR
func02
MOV R6, #06
BX LR
5 PC
Program Counter(PC)
,程序計數寄存器,這個寄存器的Bit [0]
始終爲0
,所以指令的對齊方式是按照四個字節(一個字)或者兩個字節(半字)來對齊的。
LDR LR, =func01
LDR PC, =func03
B .
func01
MOV R5, #05
BX LR
func02
MOV R6, #06
BX LR
func03
MOV R7, #07
MOV R8, #08
BX LR
這個程序程序爲直接將func03
標籤的地址裝載到PC
寄存器,因此程序會直接跳轉到func03
,因爲之前將func01
裝載到LR
寄存器,因此最終會調用函數func01
。
6 PSR
程序狀態寄存器(Program Status Register
),記錄 ALU 標誌(0 標誌,進位標誌,負數標誌,溢出標誌),執行狀態,以及當前正服務的中斷號,整體如下圖所示;
- APSR:Application PSR;記錄 ALU 標誌(0 標誌,進位標誌,負數標誌,溢出標誌)
- IPSR: Interrupt PSR;正服務的中斷號;
- EPSR:Execution PSR;執行狀態;
- xPSR:保存狀態寄存器;
7 中斷屏蔽寄存器
- BASEPRI:禁止所有優先級不高於某個具體數值的中斷;
- PRIMASK:禁止所有的中斷(除了不可屏蔽中斷外
NMI
); - FAULTMASK:禁止所有硬件錯誤導致的硬件上訪中斷;
8 總結
從cortex-m3
內核對ARM
架構的寄存器進行初步的瞭解,包括有哪些寄存器,以及這些寄存器的作用,配合簡單的代碼,從而加深理解,另外由於筆者能力有限,文中難免存在錯誤和紕漏,望大佬不吝賜教。
Cortex™-M3 Technical Reference Manual ↩︎