S3c2440ARM異常與中斷體系詳解2---CPU模式(Mode)狀態(State)
2021-09-10 來源:eefocus
這節課我們來講CPU的工作模式(Mode) 狀態(State)寄存器
7種Mode:
usr(用戶模式)
sys(系統模式)
undefined(und)(未定義模式)
Supervisor(svc)(管理者模式)
Abort(abt)(中止模式)
IRQ(irq)(中斷模式)
FIQ(fiq)(快速中斷模式)
2種State:
ARM state
Thumb state
寄存器:
通用寄存器
備份寄存器(banked register)
當前程序狀態寄存器(Current Program Status Register);CPSR
CPSR的備份寄存器:SPSR(Save Program Status Register)
我們仍然以這個母親為例講解這個CPU模式
這個母親無壓力看書 –>(正常模式)
要考試,看書—>(興奮模式)
生病—->(異常模式)
可以參考書籍 《ARM體系結構與編程》作者:杜春雷
對于ARM CPU有7種模式:
1 、usr :類比 正常模式
2 、sys :類比的話興奮模式
3 、5種異常模式:(2440用戶手冊72頁)
3.1 und :未定義模式
3.2 svc :管理模式
3.3 abt :中止模式: a 指令預取中止(讀寫某條錯誤的指令導致終止運行) b 數據訪問終止 (讀寫某個地址, 這個過程出錯) ,例如:都會進入終止模式
3.4 IRQ: 中斷模式
3.5 FIQ: 快中斷模式
我們可以稱以下6種為特權模式
und :未定義模式
svc :管理模式
abt :終止模式
IRQ :中斷模式
FIQ :快中斷模式
sys :系統模式
usr用戶模式(不可直接進入其他模式) ,特權模式可以編程操作CPSR直接進入其他模式
這個圖是有關各個模式下能訪問寄存器的,再講這個圖之前我們先引入 2種state
CPU有兩種state:
1 ARM state:使用ARM指令集,每個指令4byte
2 Thumb state:使用的是Thumb指令集,每個指令2byte
比如同樣是:
mov R0, R1 編譯后
對于ARM指令集要占據4個字節:機器碼
對于Thumb指令集占據2個字節:機器碼
引入Thumb減少存儲空間
ARM指令集與Thumb指令集的區別:
Thumb 指令可以看作是 ARM 指令壓縮形式的子集,是針對代碼密度的問題而提出的,它具有 16 位的代碼密度但是它不如ARM指令的效率高 .
Thumb 不是一個完整的體系結構,不能指望處理只執行Thumb 指令而不支持 ARM 指令集.
因此,Thumb 指令只需要支持通用功能,必要時可以借助于完善的 ARM 指令集,比如,所有異常自動進入 ARM 狀態.在編寫 Thumb 指令時,先要使用偽指令 CODE16 聲明,而且在 ARM 指令中要使用 BX指令跳轉到 Thumb 指令,以切換處理器狀態.編寫 ARM 指令時,則可使用偽指令 CODE32聲明.
下節課會演示使用Thumb指令集編譯,看是否生成的bin文件會變小很多
在每種模式下都有R0 ~ R15
在這張圖注意到有些寄存器畫有灰色的三角形,表示訪問該模式下訪問的專屬寄存器
比如
mov R0, R8
mov R0, R8
在System 模式下訪問的是R0 ~ R8,在所有模式下訪問R0都是同一個寄存器
mov R0,R8_fiq
但是在FIQ模式下,訪問R8是訪問的FIQ模式專屬的R8寄存器,不是同一個物理上的寄存器
在這五種異常模式中每個模式都有自己專屬的R13 R14寄存器,R13用作SP(棧) R14用作LR(返回地址)
LR是用來保存發生異常時的指令地址
為什么快中斷(FIQ)有那么多專屬寄存器,這些寄存器稱為備份寄存器
回顧一下中斷的處理過程
1 保存現場(保存被中斷模式的寄存器)
就比如說我們的程序正在系統模式/用戶模式下運行,當你發生中斷時,需要把R0 ~ R14這些寄存器全部保存下來,讓后處理異常,最后恢復這些寄存器
但如果是快中斷,那么我就不需要保存 系統/用戶模式下的R8 ~ R12這幾個寄存器,在FIQ模式下有自己專屬的R8 ~ R12寄存器,省略保存寄存器的時間,加快處理速度
但是在Linux中并不會使用FIQ模式
2 處理
3 恢復現場
CRSR當前程序狀態寄存器,這是一個特別重要的寄存器
SPSR保存的程序狀態寄存器,他們格式如下:
首先 M4 ~ M0 表示當前CPU處于哪一種模式(Mode);
我們可以讀取這5位來判斷CPU處于哪一種模式,也可以修改這一種模式位,讓其修改這種模式;
假如你當前處于用戶模式下,是沒有權限修改這些位的;
M4 ~ M0對應什么值,會有說明
查看其他位
Bit5 State bits表示CPU工作與Thumb State還是ARM State用的指令集是什么
Bit6 FIQ disable當bit6等于1時,FIQ是不工作的
Bit7 IRQ disable當bit5等于1時,禁止所有的IRQ中斷,這個位是IRQ的總開關
Bit8 ~ Bit27是保留位
Bite28 ~ Bit31是狀態位,
什么是狀態位,比如說執行一條指令
cmp R0, R1
如果R0 等于 R1 那么zero位等于1,這條指令影響 Z 位,如果R0 == R1,則Z = 1
beq跳轉到xxx這條指令會判斷Bit30是否為1,是1的話則跳轉,不是1的話則不會跳轉
使用 Z 位,如果 Z 位等于1 則跳轉,這些指令是借助狀態位實現的
SPSR保存的程序狀態寄存器:
表示發生異常時這個寄存器會用來保存被中斷的模式下他的CPSR
就比如我我的程序在系統模式下運行 CPSR是某個值,當發生中斷時會進入irq模式,這個CPSR_irq就保存系統模式下的CPSR
我們來看看發生異常時CPU是如何協同工作的:
進入異常的處理流程(硬件)
我們來翻譯一下:
發生異常時,我們的CPU會做什么事情
1把下一條指令的地址保存在LR寄存器里(某種異常模式的LR等于被中斷的下一條指令的地址)
它有可能是PC + 4有可能是PC + 8,到底是那種取決于不同的情況
2 把CPSR保存在SPSR里面(某一種異常模式下SPSR里面的值等于CPSR)
3 修改CPSR的模式為進入異常模式(修改CPSR的M4 ~ M0進入異常模式)
4 跳到向量表
退出異常怎么做?
1、讓LR減去某個值,讓后賦值給PC(PC = 某個異常LR寄存器減去 offset)
減去什么值呢?
也就是我們怎么返回去繼續執行原來的程序,根據下面這個表來取值
如果發生的是SWI可以把 R14_svc復制給PC
如果發生的是IRQ可以把R14_irq的值減去4賦值給PC
2、把CPSR的值恢復(CPSR 值等于 某一個一場模式下的SPSR)
3、清中斷(如果是中斷的話,對于其他異常不用設置)