日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

强制生成32位arm程序_3. 从0开始学ARM-ARM模式、寄存器、流水线

發布時間:2024/9/3 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 强制生成32位arm程序_3. 从0开始学ARM-ARM模式、寄存器、流水线 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

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

一口網Linux:嵌入式工程師到底要不要學習ARM匯編指令?

一口網Linux:1. 從0開始學ARM-安裝Keil MDK uVision集成開發環境

一口網Linux: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模式,如下圖所示:

    ARM之所以設計出這么多種模式出來,就是為了「應對CPU在運行時各種突發事件」,比如要支持正常的應用程序的運行,在運行任何一個時間點又可能發生很多異常事件,比如:關機、收到網卡信息、除數為0、訪問非法內存、解析到了非法指令等等,不光要能處理這些異常還要能夠從異常中再返回到原來的程序繼續執行。

  • 用戶模式: 用戶模式是用戶程序的工作模式,它運行在操作系統的用戶態,它沒有權限去操作其它硬件資源,只能執行處理自己的數據,也不能切換到其它模式下,要想訪問硬件資源或切換到其它模式只能通過軟中斷或產生異常。
  • 系統模式: 系統模式是特權模式,不受用戶模式的限制。用戶模式和系統模式共用一套寄存器,操作系統在該模式下可以方便的訪問用戶模式的寄存器,而且操作系統的一些特權任務可以使用這個模式訪問一些受控的資源。
  • 一般中斷模式: 一般中斷模式也叫普通中斷模式,用于處理一般的中斷請求,通常在硬件產生中斷信號之后自動進入該模式,該模式為特權模式,可以自由訪問系統硬件資源。
  • 快速中斷模式: 快速中斷模式是相對一般中斷模式而言的,它是用來處理對時間要求比較緊急的中斷請求,主要用于高速數據傳輸及通道處理中。
  • 管理模式: 管理模式是「CPU上電后默認模式」,因此在該模式下主要用來做系統的初始化,軟中斷處理也在該模式下,當用戶模式下的用戶程序請求使用硬件資源時通過軟件中斷進入該模式。
  • 終止模式: 中止模式用于支持虛擬內存或存儲器保護,當用戶程序訪問非法地址,沒有權限讀取的內存地址時,會進入該模式,linux下編程時經常出現的segment fault通常都是在該模式下拋出返回的。
  • 未定義模式: 未定義模式用于支持硬件協處理器的軟件仿真,CPU在指令的譯碼階段不能識別該指令操作時,會進入未定義模式。
  • Monitor: 是為了安全而擴展出的用于執行安全監控代碼的模式;也是一種特權模式
  • 除用戶模式以外,其余的所有6種模式稱之為非用戶模式,或特權模式(Privileged Modes);其中除去用戶模式和系統模式以外的5種又稱為異常模式(ExceptionModes),常用于處理中斷或異常,以及需要訪問受保護的系統資源等情況。

    2. 模式切換

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

    3. 異常(Exception)

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

    4. 異常源

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

    異常源描述

    5. 異常源與模式關系

  • 重啟異常進入管理模式;
  • 快速中斷請求異常進入快中斷模式,支持高速數傳輸及通道處理(FIQ異常響應時進入此模式);
  • 中斷請求異常進入中斷模式,用于通用中斷處理,(IRQ異常響應時進入此模式);
  • 預取指中止,數據中止異常進入中止模式,用于支持虛擬內存和/或存儲器保護;
  • 未定義指令異常進入未定義模式,支持硬件協處理器的軟件仿真(未定義指令異常響應時進入此模式) ;
  • 軟件中斷,復位異常進入管理模式,操作系統保護代碼(系統復位和軟件中斷響應時進入此模式) ;
  • 異常發生之后,CPU必須要立刻做出響應,關于異常后面會詳細講解。

    四、ARM寄存器

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


    通用寄存器包括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格式如下:

  • 條件碼標志(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模式可訪問的寄存器

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

    五、協處理器

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

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

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

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

  • 用于ARM處理器初始化ARM協處理器的數據操作
  • 用于ARM處理器的寄存器和ARM協處理器的寄存器間的數據傳送操作
  • 用于在ARM協處理器的寄存器和內存單元之間傳送數據
  • 這些指令包括如下5條:

  • CDP協處理器數據操作指令
  • LDC協處理器數據讀入指令
  • STC協處理器數據寫入指令
  • MCR ARM寄存器到協處理器寄存器的數據傳送指令
  • MRC 協處理器寄存器到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)執行 處理指令并將結果寫回寄存器。

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

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

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

  • 提高時鐘頻率。時鐘頻率的提高,必然引起指令執行周期的縮短,所以要求簡化流水線每一級的邏輯,流水線的級數都要增加。
  • 減少每條指令的平均指令周期數CPI。這就要求重新考慮3級流水線ARM中多余1個流水線周期的實現方法,以便使其占有較少的周期,或者減少因指令相關造成的流水線停頓,也可以將兩者結合起來。
  • 較高性能的ARM核使用了5級流水線,而且具有分開的指令和數據存儲器。 在Cortex-A8中有一條13級的流水線,但是ARM公司沒有對其中的技術公開任何相關的細節。

    從經典ARM系列到現在Cortex系列,ARM處理器的結構在向復雜的階段發展,但沒改變的是CPU的取址指令和地址關系,「不管是幾級流水線,都可以按照最初的3級流水線的操作特性來判斷其當前的PC位置」。

    2. 流水線舉例

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

    1)最佳流水線

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

    2)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)中。

  • 分支指令在其第一周期計算分支的目的地,同時在現行PC處完成一次指令預取,流水線被阻斷。這種預取在任何情況下都要做的,因為當判決地址產生時已來不及停止預取。
  • 第二個周期在分支的目標地址完成取指,而返回地址則存于R14如果link位已設置。
  • 第三周期完成目標地址+4的取指,重新填滿流水線,并且如果跳轉是帶鏈接的還要修改R14(減去4)以便簡單地返回。
  • 分支需要三個時鐘周期來執行BL,隨后會涉及調整階段。
  • 4)中斷流水線

    「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

    總結

    以上是生活随笔為你收集整理的强制生成32位arm程序_3. 从0开始学ARM-ARM模式、寄存器、流水线的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。