您現在的位置是:首頁 > 垂釣

3. 從0開始學ARM-ARM模式、暫存器、流水線

  • 由 一口Linux 發表于 垂釣
  • 2022-01-01
簡介4. 異常源要進入異常模式,一定要有異常源,ARM規定有7種異常源:異常源描述Reset上電時執行Undef當流水線中的某個非法指令到達執行狀態時執行SWI當一個軟中斷指令被執行完的時候執行Prefetch當一個指令被從記憶體中預取時,由於

cpu的指令系統又被稱為什麼

關於ARM的一些基本概念,大家可以參考我之前的文章:

《嵌入式工程師到底要不要學習ARM彙編指令?》

《到底什麼是Cortex、ARMv8、arm架構、ARM指令集、soc?一文幫你梳理基礎概念【科普】》

關於ARM指令用到的IDE開發環境可以參考下面這篇文章

《1。 從0開始學ARM-安裝Keil MDK uVision整合開發環境》

《2。 從0開始學ARM-CPU原理,基於ARM的SOC講解》

有了計算機硬體架構的原理,下面我就可以學習ARM模式、暫存器、流水線等基礎知識。

一、ARM技術特徵

ARM的成功,一方面得益於它獨特的公司運作模式,另一方面,當然來自於ARM處理器自身的優良效能。作為一種先進的RISC處理器,ARM處理器有如下特點。

體積小、低功耗、低成本、高效能。

支援Thumb(16位)/ARM(32位)雙指令集,能很好地相容8位/16位器件。

大量使用暫存器,指令執行速度更快。

大多數資料操作都在暫存器中完成。

定址方式靈活簡單,執行效率高。

指令長度固定。

二、ARM的基本資料型別

ARM採用的是32位架構,ARM的基本資料型別有以下3種。

Byte:位元組,8bit。

Halfword:半字,16bit(半字必須與2位元組邊界對齊)。

Word:字,32bit(字必須與4位元組邊界對齊)。 儲存器可以看做是序號為0~2^32^-1的線性位元組陣列。每一個位元組都有唯一的地址。

注意:

ARM系統結構v4以上版本支援以上3種資料型別,v4以前版本僅支援位元組和字。

當將這些資料型別中的任意一種宣告成unsigned型別時,n位資料值表示範圍為0~2^n^-1的非負數,通常使用二進位制格式。

當將這些資料型別的任意一種宣告成signed型別時,n位資料值表示範圍為-2^n-1^~2^n-1^-1的整數,使用二進位制的補碼格式。

所有資料型別指令的運算元都是字型別的,如“ADD r1,r0,#0x1”中的運算元“0x1”就是以字型別資料處理的。

Load/Store 資料傳輸指令可以從儲存器存取傳輸資料,這些資料可以是位元組、半字、字。載入時自動進行位元組或半字的零擴充套件或符號擴充套件。對應的指令分別為LDR/BSTRB(位元組操作)、LDRH/STRH(半字操作)、LDR/STR(字操作)。

ARM指令編譯後是4個位元組(與字邊界對齊);Thumb指令編譯後是2個位元組(與半字邊界對齊)。

三、ARM處理器工作模式

Cortex系列之前的ARM處理器工作模式一共有7種。

1. 工作模式

Cortex系列的ARM處理器工作模式有8種,多了1個monitor模式,如下圖所示:

3. 從0開始學ARM-ARM模式、暫存器、流水線

ARM處理器工作模式

ARM之所以設計出這麼多種模式出來,就是為了

「應對CPU在執行時各種突發事件」

,比如要支援正常的應用程式的執行,在執行任何一個時間點又可能發生很多異常事件,比如:關機、收到網絡卡資訊、除數為0、訪問非法記憶體、解析到了非法指令等等,不光要能處理這些異常還要能夠從異常中再返回到原來的程式繼續執行。

使用者模式: 使用者模式是使用者程式的工作模式,它執行在作業系統的使用者態,它沒有許可權去操作其它硬體資源,只能執行處理自己的資料,也不能切換到其它模式下,要想訪問硬體資源或切換到其它模式只能透過軟中斷或產生異常。

系統模式: 系統模式是特權模式,不受使用者模式的限制。使用者模式和系統模式共用一套暫存器,作業系統在該模式下可以方便的訪問使用者模式的暫存器,而且作業系統的一些特權任務可以使用這個模式訪問一些受控的資源。

一般中斷模式: 一般中斷模式也叫普通中斷模式,用於處理一般的中斷請求,通常在硬體產生中斷訊號之後自動進入該模式,該模式為特權模式,可以自由訪問系統硬體資源。

快速中斷模式: 快速中斷模式是相對一般中斷模式而言的,它是用來處理對時間要求比較緊急的中斷請求,主要用於高速資料傳輸及通道處理中。

管理模式: 管理模式是

「CPU上電後預設模式」

,因此在該模式下主要用來做系統的初始化,軟中斷處理也在該模式下,當用戶模式下的使用者程式請求使用硬體資源時透過軟體中斷進入該模式。

終止模式: 中止模式用於支援虛擬記憶體或儲存器保護,當用戶程式訪問非法地址,沒有許可權讀取的記憶體地址時,會進入該模式,linux下程式設計時經常出現的segment fault通常都是在該模式下丟擲返回的。

未定義模式: 未定義模式用於支援硬體協處理器的軟體模擬,CPU在指令的譯碼階段不能識別該指令操作時,會進入未定義模式。

Monitor: 是為了安全而擴展出的用於執行安全監控程式碼的模式;也是一種特權模式

除使用者模式以外,其餘的所有6種模式稱之為非使用者模式,或特權模式(Privileged Modes);其中除去使用者模式和系統模式以外的5種又稱為異常模式(ExceptionModes),常用於處理中斷或異常,以及需要訪問受保護的系統資源等情況。

2. 模式切換

ARM微處理器的執行模式可以透過軟體改變,也可以透過外部中斷或異常處理改變。應用程式執行在使用者模式下,當處理器執行在使用者模式下時,某些被保護的系統資源是不能被訪問的。

3. 異常(Exception)

指由處理器執行指令導致原來執行程式的中止,異常與指令執行相關,是CPU執行程式產生的,是同步的,可分為精確異常和非精確異常。異常處理遵守嚴格的程式順序,不能巢狀,只有當第一個異常處理完並返回後才能處理後續的異常。

4. 異常源

要進入異常模式,一定要有異常源,ARM規定有7種異常源:

異常源

描述

Reset

上電時執行

Undef

當流水線中的某個非法指令到達執行狀態時執行

SWI

當一個軟中斷指令被執行完的時候執行

Prefetch

當一個指令被從記憶體中預取時,由於某種原因而失敗,如果它能到達執行狀態這個異常才會產生

Data

如果一個預取指令試圖存取一個非法的記憶體單元,這時異常產生

IRQ

通常的中斷

FIQ

快速中斷

5. 異常源於模式關係

重啟異常進入管理模式;

快速中斷請求異常進入快中斷模式,支援高速數傳輸及通道處理(FIQ異常響應時進入此模式);

中斷請求異常進入中斷模式,用於通用中斷處理,(IRQ異常響應時進入此模式);

預取指中止,資料中止異常進入中止模式,用於支援虛擬記憶體和/或儲存器保護;

未定義指令異常進入未定義模式,支援硬體協處理器的軟體模擬(未定義指令異常響應時進入此模式) ;

軟體中斷,復位異常進入管理模式,作業系統保護程式碼(系統復位和軟體中斷響應時進入此模式) ;

異常發生之後,CPU必須要立刻做出響應,關於異常後面會詳細講解。

四、ARM暫存器

Cortex A系列ARM處理器共有40個32位暫存器,其中33個為通用暫存器,7個為狀態暫存器。usr模式和sys模式共用同一組暫存器。

3. 從0開始學ARM-ARM模式、暫存器、流水線

通用暫存器包括R0~R15,可以分為3類:

未分組暫存器R0~R7

分組暫存器R8~R14、R13(SP) 、R14(LR)

程式計數器PC(R15)、R8_fiq-R12_fir為快中斷獨有

1. 未分組暫存器R0~R7

在所有執行模式下,未分組暫存器都指向同一個物理暫存器,它們未被系統用作特殊的用途。因此在中斷或異常處理進行執行模式轉換時,由於不同的處理器執行模式均使用相同的物理暫存器,所以可能造成暫存器中資料的破壞。

2. 分組暫存器R8~R14

對於分組暫存器,它們每一次所訪問的物理暫存器都與當前處理器的執行模式有關。

對於R8~R12來說,每個暫存器對應2個不同的物理暫存器,當使用FIQ(快速中斷模式)時,訪問暫存器 R8_fiq~R12_fiq;當使用除FIQ模式以外的其他模式時,訪問暫存器R8_usr~R12_usr。

對於R13,R14來說,每個暫存器對應7個不同的物理暫存器,其中一個是使用者模式與系統模式共用,另外6個物理暫存器對應其他6種不同的執行模式,並採用以下記號來區分不同的物理暫存器:

R13_mode    R14_mode

其中mode可為:

「usr,fiq,irq,svc,abt,und,mon」

3. 暫存器R13(sp)

在ARM指令中常用作

「堆疊指標」

,使用者也可使用其他的暫存器作為堆疊指標,而在Thumb指令集中,某些指令強制性的要求使用R13作為堆疊指標。

暫存器R13在ARM指令中常用作堆疊指標,但這只是一種習慣用法,使用者也可使用其他的暫存器作為堆疊指標。而在Thumb指令集中,某些指令強制性的要求使用R13作為堆疊指標。

由於處理器的每種執行模式均有自己獨立的物理暫存器R13,在使用者應用程式的初始化部分,一般都要初始化每種模式下的R13,使其指向該執行模式的棧空間。這樣,當程式的執行進入異常模式時,可以將需要保護的暫存器放入R13所指向的堆疊,而當程式從異常模式返回時,則從對應的堆疊中恢復,採用這種方式可以保證異常發生後程序的正常執行。

4. R14(LR)

連結

暫存器(Link Register)

當執行子程式呼叫指令(BL)時,R14可得到R15(程式計數器PC)的備份。

在每一種執行模式下,都可用R14儲存子程式的返回地址,當用BL或BLX指令呼叫子程式時,將PC的當前值複製給R14,執行完子程式後,又將R14的值複製回PC,即可完成子程式的呼叫返回。以上的描述可用指令完成。

從子程式返回:

「方法1:」

MOV PC, LR或者  BX LR

「方法2:」

在子程式入口處使用以下指令將R14存入堆疊:

STMFD SP!,{,LR}

對應的,使用以下指令可以完成子程式返回:

LDMFD SP!,{,PC}

5. R15(PC)程式狀態暫存器

暫存器R15用作程式計數器(PC),在ARM狀態下,位[1:0]為0,位[31:2]用於儲存PC,在Thumb狀態下,位[0]為0,位[31:1]用於儲存PC。

比如如果pc的值是0x40008001,那麼在定址的時候其實會查詢地址0x40008000,低2位會自動忽略掉。

「箇中原因,請讀者自己思考?」

由於ARM體系結構採用了多級流水線技術,對於ARM指令集而言,PC總是指向當前指令的下兩條指令的地址,即PC的值為當前指令的地址值加8個位元組。

即:PC值=當前程式執行位置+8

【流水線技術參考第七章】

6. CPSR、SPSR

「CPSR」

(Current Program Status Register,當前程式狀態暫存器),CPSR可在任何執行模式下被訪問,它包括條件標誌位、中斷禁止位、當前處理器模式標誌位,以及其他一些相關的控制和狀態位。

每一種執行模式下又都有一個專用的物理狀態暫存器,稱為

「SPSR」

(Saved Program Status Register,備份的程式狀態暫存器),當異常發生時,SPSR用於儲存CPSR的當前值,從異常退出時則可由SPSR來恢復CPSR。

由於使用者模式和系統模式不屬於異常模式,它們沒有SPSR,當在這兩種模式下訪問SPSR,結果是未知的。

暫存器CPSR格式如下:

3. 從0開始學ARM-ARM模式、暫存器、流水線

CPSR

條件碼標誌(condition code flags)

「N,Z,C,V」

均為條件碼標誌位,它們的內容可被算術或邏輯運算的結果所改變,並且可以決定某條指令是否被執行。 在ARM狀態下,絕大多數的指令都是有條件執行的,在Thumb狀態下,僅有分支指令是有條件執行的。

「N (Number)」

: 當用兩個補碼錶示的帶符號數進行運算時,N=1表示執行結果為負,N=0表示執行結果為正或零

「Z :(Zero)」

: Z=1表示運算結果為零,Z=0表示執行結果非零

「C」

: 可以有4種方法設定C的值:

(Come)加法運算(包括CMP):當運算結果產生了進位時C=1,否則C=0

減法運算(包括CMP):當運算產生了借位,C=0否則C=1

對於包含移位操作的非加/減運算指令 ,C為移出值的最後一位

對於其他的非加/減運算指令C的值通常不改變

「V」

(oVerflow)對於加/減法運算指令,當運算元和運算結果為二進位制的補碼錶示的帶符號位溢位時,V=1表示符號位溢位;對於其他的非加/減運算指令V的值通常不改變

「Q」

: 在ARM V5及以上版本的E系列處理器中,用Q標誌位指示增強的DSP運算指令是否發生了溢位。在其它版本的處理器中,Q標誌位無定義

「J:」

僅ARM v5TE-J架構支援 , T=0;J = 1 處理器處於Jazelle狀態,也可以和其他位組合。

「E位:」

大小端控制位

「A位:」

A=1 禁止不精確的資料異常

「T :」

T = 0;J=0; 處理器處於 ARM 狀態 T = 1;J=0 處理器處於 Thumb 狀態 T = 1;J=1 處理器處於 ThumbEE 狀態

控制位 CPSR的

8位(包括I,F,T和M[4:0])稱為控制位,當發生異常時這些位可以被改變,如果處理器執行特權模式,這些位也可以由程式修改。

「中斷禁止位I,F」

【重要】 I=1 禁止IRQ中斷 F=1 禁止FIQ中斷

比如我們要想在程式中實現禁止中斷,那麼就需要將CPSR[7]置1。

執行模式

[4-0]

bite

模式

ARM模式可訪問的暫存器

0b10000

使用者模式user

PC,CPSR,R0~R14

0b10001

FIQ模式

PC,CPSR,SPSR_fiq,R14_fiq~R8_fiq,R0~R7

0b10010

IRQ模式

PC,CPSR,SPSR_irq,R14_irq~R13_irq,R0~R12

0b10011

管理模式

PC,CPSR,SPSR_svc,R14_svc~R13_svc,R0~R12

0b10111

中止模式Abort

PC,CPSR,SPSR_abt,R14_abt~R13_abt,R0~R12

0b11011

未定義模式

C,CPSR,SPSR_und,R14_und~R13_und,R0~R12

0b11111

系統模式

PC,CPSR,R0~R14

注意觀察這5個bit的特點,最高位都是1,低4位的值則各不相同,這個很重要,要想搞清楚uboot、linux的原始碼,尤其是異常操作的程式碼,必須要知道這幾個bit的值。

五、協處理器

3. 從0開始學ARM-ARM模式、暫存器、流水線

ARM體系結構允許透過增加協處理器來擴充套件指令集。最常用的協處理器是用於控制片上功能的系統協處理器。

例如,控制Cache和儲存管理單元MMU的CP15協處理器、設定異常向量表地址的mcr指令。

ARM支援16個協處理器,在程式執行過程中,每個協處理器忽略屬於ARM處理器和其他協處理器指令,當一個協處理器硬體不能執行屬於她的協處理器指令時,就會產生一個未定義的異常中斷,在異常中斷處理程式中,可以透過軟體模擬該硬體的操作,比如,如果系統不包含向量浮點運算器,則可以選擇浮點運算軟體模擬包來支援向量浮點運算。

ARM協處理器指令包括如下三類:

用於ARM處理器初始化ARM協處理器的資料操作

用於ARM處理器的暫存器和ARM協處理器的暫存器間的資料傳送操作

用於在ARM協處理器的暫存器和記憶體單元之間傳送資料

這些指令包括如下5條:

CDP協處理器資料操作指令

LDC協處理器資料讀入指令

STC協處理器資料寫入指令

MCR ARM暫存器到協處理器暫存器的資料傳送指令

MRC 協處理器暫存器到ARM暫存器的資料傳送指令

關於協處理器指令,我們只需要知道幾個常用的即可,後面文章會提到。

六、Jazelle

3. 從0開始學ARM-ARM模式、暫存器、流水線

Jazelle

Jazelle傑則來 或者說Java位元組碼狀態是為了執行Java虛擬機器而新增的一種狀態。

ARM的Jazelle技術在硬體上提供了對Java位元組碼的支援,大大提高了系統的效能。

由於ARM 架構是32-bits,16-bits = “halfword” , “word” = 32-bits。

Java 位元組碼 8-bits 獨立架構的指令集。Jazelle 用硬體執行大多數的位元組碼(另一些使用高度優化了的ARM 程式碼)。這是由於折衷了硬體複雜度(功耗 & 矽片面積)和速度。

七、指令流水線

流水線技術透過多個功能部件並行工作來縮短程式執行時間,提高處理器核的效率和吞吐率,從而成為微處理器設計中最為重要的技術之一。

1. 3級流水線

到ARM7為止的ARM處理器使用簡單的3級流水線,它包括下列流水線級。 (1)取指令 從暫存器裝載一條指令。 (2)譯碼(decode) 識別被執行的指令,併為下一個週期準備資料通路的控制訊號。在這一級,指令佔有譯碼邏輯,不佔用資料通路。 (3)執行 處理指令並將結果寫回暫存器。

3. 從0開始學ARM-ARM模式、暫存器、流水線

指令的執行

當處理器執行簡單的資料處理指令時,流水線使得平均每個時鐘週期能完成1條指令。但一條指令需要3個時鐘週期來完成,因此有3個時鐘週期的延時,但吞吐率是每個週期一條指令。

對於3級流水線,PC暫存器裡的值並不是正在執行的指令的地址,而是預取指令的地址,這個知識點很重要,後面我們會詳細的舉例來證明。

處理器要滿足高效能的要求,為了滿足這個要求,需要重新考慮處理器的組織結構。 提高效能的方法主要有兩種方法:

提高時鐘頻率。時鐘頻率的提高,必然引起指令執行週期的縮短,所以要求簡化流水線每一級的邏輯,流水線的級數都要增加。

減少每條指令的平均指令週期數CPI。這就要求重新考慮3級流水線ARM中多餘1個流水線週期的實現方法,以便使其佔有較少的週期,或者減少因指令相關造成的流水線停頓,也可以將兩者結合起來。

較高效能的ARM核使用了5級流水線,而且具有分開的指令和資料儲存器。 在Cortex-A8中有一條13級的流水線,但是ARM公司沒有對其中的技術公開任何相關的細節。

從經典ARM系列到現在Cortex系列,ARM處理器的結構在向複雜的階段發展,但沒改變的是CPU的取址指令和地址關係,

「不管是幾級流水線,都可以按照最初的3級流水線的操作特性來判斷其當前的PC位置」

2. 流水線舉例

為方便理解,下面我們以3級流水線為例,

1)最佳流水線

3. 從0開始學ARM-ARM模式、暫存器、流水線

最佳流水線

這是一個理想的例項,所有的指令都在暫存器中執行,且處理器完全不必離開晶片本身。每個週期,都有一條指令被執行,流水線的容量得到了充分的發揮。 指令週期數 (CPI) = 1

2)LDR流水線

3. 從0開始學ARM-ARM模式、暫存器、流水線

LDR流水線

該例中,用6週期執行了4條指令 指令週期數 (CPI) = 1。5

與最佳流水線不同,裝載(LDR) 操作將資料移進片內導致了指令/資料匯流排被佔用,因此隨後緊跟了內部的寫週期( writeback)以完成將資料寫回暫存器。

資料匯流排在週期1, 2, 3 被使用,週期6是取指,週期4用於資料裝載,而週期5是一個內部週期用來完成載入的資料寫回到暫存器中。

週期3為執行週期:產生地址

週期4為資料週期:從儲存器中取資料(資料只有在週期4的末尾出現在核心中)

週期5寫回週期:透過資料通道中的B匯流排和ALU將資料寫回到暫存器bank 中

週期6的執行被推遲了,直到週期5寫回完成(使用ALU )。同樣內部週期是不需要等待狀體的,但讀寫儲存器時可能需要。

3)分支流水線

BL指令用於實現指令流的跳轉,並存儲返回地址到暫存器R14(LR)中。

3. 從0開始學ARM-ARM模式、暫存器、流水線

分支流水線

分支指令在其第一週期計算分支的目的地,同時在現行PC處完成一次指令預取,流水線被阻斷。這種預取在任何情況下都要做的,因為當判決地址產生時已來不及停止預取。

第二個週期在分支的目標地址完成取指,而返回地址則存於R14如果link位已設定。

第三週期完成目標地址+4的取指,重新填滿流水線,並且如果跳轉是帶連結的還要修改R14(減去4)以便簡單地返回。

分支需要三個時鐘週期來執行BL,隨後會涉及調整階段。

4)中斷流水線

3. 從0開始學ARM-ARM模式、暫存器、流水線

中斷流水線

「IRQ 中斷的反應時間最小=7週期」

週期1: 核心被告知有中斷 IRQ在現行指令執行完之前不會被響應( MUL and LDM/STM 指令會有長的延遲) 解碼階段:中斷被解碼(中斷已使能,設定了相應標誌位… )。如果中斷被使能和服務,正常的指令將不會被解碼。

週期 2: 此時總是進入ARM狀態。 執行中斷 ( 獲取IR向量的地址), 儲存 CPSR 於 SPSR, 改變CPSR模式為 IRQ 模式並禁止進一步的 IRQ 中斷輸入。

週期 3: 儲存 PC (0x800C) 於 r14_irq, 從IRQ異常處理向量處取指

週期 4: 解碼向量表中的指令; 調整r14irq 為0x8008

週期 4和 5: 無有用的指令取指, 由於週期 6的跳轉

週期 6: 取異常處理子程式的第一條指令; 從子程式返回:

SUBS pc,lr,#4

這將恢復工作模式並從響應中斷前的下一條指令處取指,如果有多箇中斷,需堆疊儲存返回地址。 注意最大的FIQ響應延遲為 29個週期(而非Thumb狀態的28週期!)。

嵌入式學習交流,請關注 一口Linux

Top