1. 程式人生 > >arm的7種執行模式

arm的7種執行模式

ARMv4以上版本的CPU任何時刻必定處於如下7種執行模式之一:
    (1) User Mode:使用者模式。作業系統的Task一般以這種模式執行。User Mode是ARM唯一的非特權模式,這表示如果CPU處於這種模式下,很多指令將不能夠執行,因此作業系統的資源得以保護。
    (2) System Mode:這是V4及其以上版本所引入的特權模式。、
    (3) IRQ Mode:中斷模式。中斷(不包括軟中斷)處理函式在這種模式下執行。
    (4) FIQ Mode:快速中斷模式。除了多了幾個暫存器外,其他同IRQ一樣。
    (5) Supervisor Mode:監視模式。軟中斷(SWI)處理函式在這種模式下執行。
    (6) Abort Mode:所有同記憶體保護相關的異常均在這種模式下執行。
    (7) Undefined Mode:處理無效指令的異常處理函式在這種模式下執行。

    程式可以通過讀取CPSR的MODE域來判斷CPU當前的執行模式。
    如何看待ARM的各種模式?要回答這個問題,我們要看不同模式下,有哪些東西不同。歸納來說,有如下兩個方面的不同:
    (1) 物理暫存器不同
    (2) 許可權不同

    如果將User Mode作為參考模式,那麼:
    (1) System Mode:暫存器一樣,僅僅是許可權不同
    (2) 其他Exception Mode:暫存器不一樣,許可權也不一樣

    從許可權的角度看,System Mode和其他Exception Mode(FIQ,IRQ,Supervisor,Abort,Undefined)是一樣的,他們之間的區別僅僅是暫存器方面有一些差別。
    從暫存器角度看,我們可以將CPSR中的MODE域看作一個類似於片選的東西,當其值不一樣,所選中的暫存器也不一樣。雖然指令中的暫存器是一樣的,但是經過MODE域的片選後,實際就指向不同的物理暫存器了。
    必須要特別注意,SYSTEM模式和USER模式除了許可權不一樣外,其他都一樣,這樣可以讓作業系統自由訪問16個暫存器(包括狀態暫存器)。

    那麼,模式切換是如何進行的呢?
    (1) 執行SWI或Reset指令。如果在User模式下執行SWI指令,CPU就進入Supervisor模式。當然,在其它模式下執行SWI指令,也會進入Supervisor模式,補過一般作業系統不會這麼做。因為除了User模式是非特權模式下,其他模式都屬於特權模式(這說明ARM只有兩種執行態,不想Dummy的X86,定義了4種執行態)。執行SWI一般是為了訪問系統資源,在特權模式下可以訪問所有的系統資源。SWI指令一般用來用來為作業系統提供API介面。
    (2) 有外部中斷髮生。如果發生了外部中斷,CPU就會進入IRQ或FIQ模式,具體是哪種模式,得看外部的中斷源是接到CPU的那個Pin。
    (3)  CPU執行過程中產生異常。最典型的異常是由於MMU保護所引起的記憶體訪問異常,此時CPU會切換到Abort模式。如果是無效指令,則會進入Undefined模式。

    從上面我們發現,有一種模式是CPU無法自動進入的,這種模式就是System模式。要進入System模式必須由程式設計師自己編寫指令來實現。其實很簡單,在任何特權模式下改變CPSR的MODE域為System模式所對應得數字即可。進入System模式一般是為了利用“System 模式”和“User 模式”下的暫存器是一樣的。因此一般作業系統在通過SWI進入Supervisor模式後,做一些簡單處理後,就進入System模式。
    另外,在任何特權模式下,都可以通過修改CPSR的MODE域而進入其他模式。不過需要注意的是,由於修改的CPSR是該模式下的影子CPSR,因此並不是實際的CPSR,所以一般的做法是修改影子CPSR,然後執行一個MOVS指令來恢復執行到某個斷點並切換到新模式。

     我們還可以將執行模式按照如下型別劃分:
     (1)  使用者模式:User Mode
     (2)  系統模式:System Mode
     (3)  異常模式:所有其它5種模式

    為什麼這樣劃分呢?這是由於異常模式同用戶模式和系統模式有一個不一樣的地方,那就是,當CPU產生中斷或異常而自動切換到相應異常模式後,CPU會根據產生中斷或異常的原因執行相應得中斷或異常向量。這些向量的位置是CPU事先定義好的,目前有兩種選擇:
    (1)   處於記憶體低地址0x00000000~0x0000001c,這種情況被稱之為Low vector
    (2)   處於記憶體高低之0Xffff0000~0xffff001c,這種情況被稱之為High vector。   
     一般的作業系統會在這些異常向量地址處放置一條跳轉指令。至於到底是使用Low vector,還是使用High vector,由CPU自己決定,ARM規範不做任何限制。