【R0~R15寄存器組】
Cortex-M3處理器擁有R0~R15的寄存器組,如:
【R0~R12通用寄存器】
R0~R12都是32位通用寄存器,用於數據操作。其中:
- R0~R7為低組寄存器,所有的指令都可以訪問。
- R8~R12為高組寄存器,只有32位Thumb2指令和很少的16位Thumb指令能訪問。
【R13堆棧指針SP】
Cortex-M3擁有兩個堆棧指針,然而它們是banked,任一時刻只能使用其中的一個。
- 主堆棧指針(MSP):復位后缺省使用的堆棧指針,用於操作系統內核以及異常處理(包括中斷服務)。
- 進程堆棧指針(PSP):由用戶的應用程序代碼使用。
【R14連接寄存器LR】
連接寄存器LR用於在調用子程序時存儲返回地址。例如,在使用BL(分支變連接,Branch and Link)指令時,就自動填充LR的值。
main ;主程序 ... BL function1 ; 使用“分支並連接”指令調用function1 ; PC=function1,並且LR=main的下一條指令地址 ... function1 ... ; function1的代碼 BX LR ; 函數返回(如果function1要使用LR,必須使用前PUSH, ; 否則返回時程序就可能跑飛了)
ARM為了減少訪問內存的次數(訪問內存的操作往往需要3個以上指令周期,帶MMU和cache的就更加不確定了),把返回地址直接存儲在寄存器中。這樣足以使很多只有1級子程序調用的代碼無需訪問內存(堆棧內存),從而提高了子程序調用的效率。如果多於1級,則需要把前一級的R14值壓到堆棧里。
在ARM上編程時,應盡量只使用寄存器保存中間結果,迫不得已才訪問內存。
在RISC處理器中,為了強調訪問內存操作越過了處理器的界線,並且帶來了對性能的不利影響,給它取了一個專業的術語:濺出。
【R15程序計數寄存器PC】
程序計數寄存器PC指向當前的程序地址。如果修改它的值,能改變程序的執行流。
因為Cortex-M3內部使用了指令流水線,讀PC時返回的值時當前指令的地址值+4,如:
0x1000: MOV R0, PC ; R0 = 0x1004
如果向PC中寫數據,就會引起一次程序的分支(但是不更新LR寄存器)。
Cortex-M3中的指令至少是半字(2字節)對齊的,所以PC的LSB總是讀回0。然而,在分支時,無論是直接寫PC的值還是使用分支指令,都必須保證加載到PC的數值是奇數(即LSB=1),用以表明這是在Thumb狀態下執行。如若寫了0,則視為企圖轉入ARM模式,Cortex-M3將產生一個fault異常。
【特殊功能寄存器組】
Cortex-M3中的特殊功能寄存器包括:
- 程序狀態寄存器組(PSRs/xPSR)
- 中斷屏蔽寄存器組(PRIMASK、FAULTMASK以及BASEPRI)
- 控制寄存器(CONTROL)
它們只能被專用的MSR/MRS指令訪問,而且它們也沒有與之相關聯的訪問地址。如:
MRS <gp_reg>, <special_reg> ; 讀特殊功能寄存器的值到通用寄存器
MSR <special_reg>, <gp_reg> ; 寫通用寄存器的值到特殊功能寄存器
【程序狀態寄存器PSRs/xPSR】
程序狀態寄存器在其內部又被分為三個子狀態寄存器:
- 應用程序PSR(APSR):
- 中斷號PSR(IPSR):
- 執行PSR(EPSR):
如:
xPSR:
通過MRS/MSR指令,這3個PSRs即可以單獨訪問,也可以組合訪問(2個組合,3個組合都可以)。
當使用三合一的方式訪問時,應使用名字“xPSR”或者“PSR”。
【中斷屏蔽寄存器PRIMASK、FAULTMASK、BASEPRI】
中斷屏蔽寄存器組(PRIMASK、FAULTMASK以及BASEPRI)用於控制“異常”的使能(enable)和除能(disable)。
- PRIMASK:這是個只有單一比特的寄存器。當它被置1后,就關掉所有可屏蔽的異常中斷,只剩下NMI和硬fault可以響應。它的缺省值為0,表示沒有關中斷。
- FAULTMASK:這是個只有單一比特的寄存器。當它被置1后,只有NMI才能響應,所有其他的異常中斷包括硬fault都不會響應。它的缺省值為0,表示沒有關異常。
- BASEPRI:這個寄存器最多有9位(由表達優先級的位數決定)。它定義了被屏蔽優先級的閾值。當它被設成某個值后,所有優先級號大於等於此值得中斷都被關閉(優先級號越大,優先級越低)。但如果被設為0,則不關閉任何中斷。它的缺省值為0。
要訪問PRIMASK、FAULTMASK、BASEPRI寄存器,同樣需要使用MRS/MSR指令,並且只有在特權級下,才允許訪問這3個寄存器。
如:
MRS R0, BASEPRI ; 讀取BASEPRI到R0中
MRS R0, FAULTMASK ; 讀取FAULTMASK到R0中
MRS R0, PRIMASK ; 讀取PRIMASK到R0中
MSR BASEPRI, R0 ; 寫入R0到BASEPRI中
MSR FAULTMASK, R0 ;
MSR PRIMASK, R0 ;
** 只有在特權級下,才允許訪問這3個寄存器 **
【控制寄存器CONTROL】
控制寄存器有兩個用途,其一用於定義特權級別(CONTROL[0]),其二用於選擇當前使用哪個堆棧指針(CONTROL[1])。
CONTROL[0]:
- 0 = 特權級的線程模式
- 1 = 用戶級的線程模式
Handler模式永遠都是特權級的。
CONTROL[1]:
- 0 = 選擇主堆棧指針MSP(復位后的缺省值)
- 1 = 選擇進程堆棧指針PSP
Handler模式下只允許使用MSP。
由於Handler模式下用於都是特權級的,且只允許使用MSP;可見這個寄存器主要用於“線程模式”下的設置。
在線程模式下,可設置為特權級的線程模式或非特權級的線程模式;使用MSP或使用PSP。
參考摘錄:《ARM Cortex-M3權威指南.pdf》