工作模式_ufisaus
| USR | FRQ | IRQ | SVC | ABT | UND | SYS |
|---|---|---|---|---|---|---|
| R0 | ||||||
| R1 | ||||||
| R2 | ||||||
| R3 | ||||||
| R4 | ||||||
| R5 | ||||||
| R6 | ||||||
| R7 | ||||||
| R8 | R8_FRQ | |||||
| R9 | R9_FRQ | |||||
| R10 | R10_FRQ | |||||
| R11 | R11_FRQ | |||||
| R12 | R12_FRQ | |||||
| SP | SP_FRQ | SP_IRQ | SP_SVC | SP_ABT | SP_UND | |
| LR | LR_FRQ | LR_IRQ | LR_SVC | LR_ABT | LR_UND | |
| PC | ||||||
| CPSR | ||||||
| SPSR_FRQ | SPSR_IRQ | SPSR_SVC | SPSR_UND | SPSR_ABT |
- USR(User) :正常程序的執行狀態
- FIQ(Fast interrupt) :用於高速數據傳輸和通道處理
- IRQ(Interrupt) :通常的中斷處理
- SVC(Supervisor) :供操作系統使用的一種保護模式,復位或執行SWI進入該模式
- ABT(Abort) :可用於虛擬存儲以及存儲保護,當數據或指令預取終止時進入該模式
- UND(Undefined) :可用於支持硬件協處理器的軟件仿真,未定義的指令執行時進入該模式
- SYS(System) :運行具有特權的操作系統任務
Note:
- 除了USR和SYS外都是異常模式
- 除了USR外都是特權模式 , 特權模式可以通過直接修改CPSR中相應的位來切換到USR,但是USR不能直接修改CPSR,只能通過指令,
- OS的內核態程序工作在SVC模式, 用戶態程序工作在USR模式
- ARM的CPU復位就處於SVC模式,執行完啟動代碼后就需要切換到USR模式
運行狀態
- ARM狀態:執行ARM指令時,32位指令,當處理器執行在ARM狀態,所有的指令必須word對齊(所有指令的起始地址都是4的整數倍),所以PC的[1:0]是沒有作用的,
- Thumb狀態:執行Thumb指令時,16位指令, 當處理器執行在thumb狀態,所有的指令必須halfword對齊,所有指令的起始地址都是2的整數倍,所以pc的[0]是沒有定義的
- Jazelleh狀態,是byte對齊的
指令/數據本身是多少位的,存儲的起始地址就是多少位的整數倍
通用寄存器
- R13 :SP,Stack Pointer,當前模式的棧指針,永遠指向棧頂,壓棧就是將寄存器的值放入棧中同時移動sp,出棧就是將棧中的值放入寄存器同時移動sp,用於保護現場,例如進行多級跳轉時,只有一個LR寄存器肯定是不夠用的,這時就可以將函數返回的地址進行壓棧,函數執行完畢再將地址出棧到PC
- R14 :LR,Link Register,保存函數調用返回的位置,存儲pc下一條指令的地址,調用函數返回之間將pc的值賦值給lr(mov pc, lr),就可以返回原程序
- R15 :PC,Program Counter,當前"執行"指令的地址+8byte,不論是多少級流水,PC永遠指向當前執行指令的下兩條位置,更多級的流水都是在"執行"之后的級數
狀態寄存器_NZCV-iftm
CPSR(Current Program Status Register):程序狀態寄存器
SPSR(Saved Process Satus Register):cpsr的備份寄存器
[31]:N, =1表示結果為Negative
[30]:Z, =1表示結果為Zero
[29]:C, =1表示計算有Carry(進位) , 如果ALU有加法運算,且產生了進位,則C位自動置1,如果ALU有減法運算,且產生了借位,則C位自動置0
[28]:V, =1表示計算有oVerflow(溢出)
[27:8]:保留
[7]:I, IRQ的屏蔽位,=1表示禁止IRQ
[6]:F, FIQ的屏蔽位,=1表示禁止FRQ ,芯片的一上電默認就是將if兩個位置1,因為初始化代碼執行期間系統還沒准備好,響應中斷沒有意義,一般在啟動代碼執行的最后手動將這兩位清0,進入系統
[5]:T, 標識當前CPU的工作狀態, =1表示執行Thumb指令 ,該位不能直接被修改,必須用過bic修改
[4:0]:M, CPU工作模式位, 任何模式都可以讀,只有特權模式可以寫
異常_firdpsur
FRQ:當硬件產生FRQ信號觸發該異常 -> FRQ
IRQ :當硬件產生IRQ信號觸發該異常 -> IRQ
PretchAbort:當取指令出錯 -> ABT
Data Abort:當取數據出錯 -> ABT
SWI :軟中斷異常,執行匯編指令 “swi” -> SVC
Undefine:CPU解碼到不認識的機器指令, -> UND
Reset:復位異常,按下復位鍵觸發該異常, -> SVC
異常向量表
早期的ARM會在0地址處放置一張表,表的每一項都對應的了發生該類異常時的處理函數的地址,現在的ARM核可以在初始化代碼中指定異常向量表的位置,不過默認還是0地址處。在ARM體系中,異常終端向量表的大小為32byte.每個異常中斷占4byte,這4byte存儲一條跳轉指令或者一個向PC寄存器中賦值的數據訪問指令,通過這兩種指令,程序跳轉到相應的異常中斷處理程序。
ARM 的異常也是有優先級的,Reset > DataAbort > FIQ > IRQ > PrefetchAbort > SWI > Undef。 在執行高優先級的異常處理程序時,不允許被低優先級的異常中斷,但是反過來可以。
FIQ比IRQ快的3個原因:
- FIQ的優先級比IRQ高,同時發生時會優先執行FRQ
- FIQ對應的FIQ模式有更多的私有寄存器,這意味着如果FIQ如果用到R8~R12這些寄存器,不需要像IRQ一樣先把原來的寄存器值進行壓棧
- FIQ在中斷向量表的最高處,這就為我們直接在FIQ上面的地址直接寫異常處理程序提供了可能,其他的異常必須通過跳轉,而跳轉就需要保存IR值
當異常產生時,硬件自動做的4件事:
- 復制CPSR寄存器的內容到
SPSR_<mode>//eg,產生了reset異常,復制內容到SPSR_<svc> - 修改CPSR寄存器
- 切換為ARM狀態 (CPSR的T位置0)
- 切換到異常模式 (CPSR的M位[4:0]置相應的值)
- 禁止必要的中斷 (CPSR的IF位置1)
- 存儲返回地址到
LR_<mode>寄存器 - 設置
PC為相應的異常入口地址
當異常處理結束,返回時軟件要做的2件事:
- 從
SPSR_<mode>恢復CPSR - 拷貝
LR_<mode>的內容到PC
