ARM Cortex-M3 技術解析:核寄存器R1-R15介紹及使用
作為嵌入式開發領域的經典處理器內核,ARM Cortex-M3(CM3)憑借其高效能、低功耗和豐富特性,在工業控制、物聯網、消費電子等領域廣泛應用。而內核寄存器是我們調試代碼,理解程序運行邏輯必不可少的好幫手,理解匯編是通往嵌入式高手的必經之路。下面本文從技術角度解析其核心架構與核寄存器做相關講解。
一、內核介紹
ARM Cortex-M3是一款面向嵌入式系統的32位RISC處理器內核,采用改進型哈佛架構,通過獨立指令總線(I-Code)和數據總線(D-Code)實現并行訪問,同時維護統一編址的4GB線性存儲空間。內核配備三級流水線(取指、譯碼、執行)與靜態分支預測機制,結合Thumb-2指令集混合16/32位編碼,在保持高代碼密度(相比純32位指令節省約30%存儲空間)的同時實現單周期32位乘法等運算能力。其嵌套向量中斷控制器(NVIC)支持240個中斷源,硬件自動完成優先級排序與現場保護,中斷響應延遲固定為12個時鐘周期,中斷嵌套深度無軟件限制。
存儲器保護單元(MPU)可劃分8個獨立區域,實現特權模式與用戶模式的訪問權限隔離,支持大小端數據格式動態切換。調試系統集成串行線/JTAG(SWJ-DP)接口,支持4個硬件斷點與2個數據觀察點,配合可選ETM指令追蹤模塊實現實時執行流記錄。電源管理模塊提供睡眠、深度睡眠和待機三種低功耗模式,休眠電流最低1μA,運行功耗典型值低于200μA/MHz(基于90nm工藝)。該內核通過AHB-Lite總線矩陣連接外設,支持單周期GPIO操作與位帶別名訪問,硬件除法器可在2-12周期內完成32位整數運算。作為首款支持非對齊內存訪問的Cortex-M系列處理器,其架構平衡了實時性、能效比與開發便利性,適用于工控、IoT等實時嵌入式場景。
二、核寄存器
Cortex‐M3 處理器擁有 R0‐R15 的寄存器組。其中 R13 作為堆棧指針 SP。SP 有兩個,但在同一時刻只能有一個可以看到,這也就是所謂的“banked”寄存器。如下圖所示的R13寄存器,分為主堆棧指針(MSP)、進程堆棧寄指針(PSP)。
R0-R12:通用寄存器
R0‐R12 都是 32 位通用寄存器,用于數據操作。但是注意:絕大多數 16 位 Thumb 指令只能訪問 R0‐R7,而 32 位 Thumb‐2 指令可以訪問所有寄存器。首先在程序的調用過程中,R0-R3寄存器都存儲著調用函數的傳參值,下一個函數用到了幾個參數,就提前將參數存儲在r0-r3里面,如果超出4個參數,就將多余的參數Push進堆棧中,在進入到調用的函數里面后,在Pop出棧給其他r4-r12寄存器。
下面我們舉個例子,函數我是用函數指針的形式寫的,你就把他當成調用一個函數,其中ptDevice,x,y,1都是傳參。我們看下面的匯編代碼,將1給到r3,將y給到r2,將x給到r1,最后將ptDevice給到r0,之后執行BLX跳轉指令,進入到該函數中。
Banked R13: 兩個堆棧指針
Cortex‐M3 擁有兩個堆棧指針,然而它們是 banked,因此任一時刻只能使用其中的一個。
- 主堆棧指針(MSP):復位后缺省使用的堆棧指針,用于操作系統內核以及異常處理例程(包括中斷服務例程)
- 進程堆棧指針(PSP):由用戶的應用程序代碼使用。
如下圖,在STM32 F103芯片中,我們能看到這兩個SP寄存器。之后我會單獨出一章講解MSP和PSP使用的場景,這里不做細講。
堆棧指針的最低兩位永遠是 0,這意味著堆棧總是 4 字節對齊的。
在 ARM 編程領域中,凡是打斷程序順序執行的事件,都被稱為異常(exception)。除了外部中斷外,當有指令執行了“非法操作”,或者訪問被禁的內存區間,因各種錯誤產生的 fault,以及不可屏蔽中斷發生時,都會打斷程序的執行,這些情況統稱為異常。在不嚴格的上下文中,異常與中斷也可以混用。另外,程序代碼也可以主動請求進入異常狀態的(常用于系統調用)。
R14:連接寄存器(LR)
當呼叫一個子程序時,由 R14 存儲返回地址。
不像大多數其它處理器,ARM 為了減少訪問內存的次數(訪問內存的操作往往要 3 個以上指令周期,帶 MMU和 cache 的就更加不確定了),把返回地址直接存儲在寄存器中。這樣足以使很多只有 1 級子程序調用的代碼無需訪問內存(堆棧內存),從而提高了子程序調用的效率。如果多于 1 級,則需要把前一級的 R14 值壓到堆棧里。在 ARM上編程時,應盡量只使用寄存器保存中間結果,迫不得以時才訪問內存。在 RISC 處理器中,為了強調訪內操作越過了處理器的界線,并且帶來了對性能的不利影響,給它取了一個專業的術語:濺出。
下面我們也再看一個例子,如下圖所示,在我們調用函數的時候,會將函數執行完返回下一行指令存儲在R14寄存器中,當執行完該函數后,就跳轉回R14寄存器,即該函數執行完的下一行代碼。執行完該跳轉指令后的下一行指令的地址是0x08001CA6,此時將0x08001CA6的值存儲在R14寄存器中,等待函數執行完,返回。由于Cortex M使用的是Thumb指令,地址跳轉的指令需要加1,即08001CA7存儲在R14寄存器中。
R15:程序計數寄存器–PC
指向當前的程序地址。如果修改它的值,就能改變程序的執行流。
其實就是程序跑到了哪里,R15就執行哪里,如下圖所示。
特殊功能寄存器
Cortex‐M3 還在內核水平上搭載了若干特殊功能寄存器,包括程序狀態字寄存器組(PSRs)中斷屏蔽寄存器組(PRIMASK, FAULTMASK, BASEPRI)控制寄存器(CONTROL)
下圖我們介紹一下STM32 F103的特殊寄存器,當我們執行CMP,BLE,CBZ等等這些匯編代碼時,這些代碼執行完都會影響狀態寄存器xPSR中的值,給后續匯編代碼執行其他跳轉、比較或者其他匯編指令的時候提供條件判斷。
下面我們就用一張STM32F1xx系列的Cortex M3的芯片將上面的核寄存器的圖片進行總結:
三、總結
Cortex-M3通過架構級優化(哈佛總線、Thumb-2指令集)與系統級增強(MPU、NVIC),在性能與功耗之間實現平衡。其完善的調試生態(Keil MDK、IAR Embedded Workbench支持)進一步降低開發門檻,成為中高端嵌入式應用的經典選擇。后續的Cortex-M4/M7等系列雖在DSP/浮點性能上強化,但M3仍憑借性價比占據重要市場地位。后續我會分享更多有關嵌入式和ARM內核方面的知識,希望大家多多關注。
擴展閱讀建議
- ARMv7-M架構手冊(了解指令集細節)
- 《Cortex-M3權威指南》(Joseph Yiu著)
- CMSIS標準庫應用(統一外設驅動接口)