ARM體系結構和彙編指令

第一節 可編程器件的編程原理

1. 可編程器件的特色

  • 1 . CPU在固定頻率的時鐘控制下節奏運行
  • 2 . CPU能夠經過總線讀取外部存儲設備中的二進制指令集,而後解碼執行
  • 3 . 這些能夠被CPU解碼執行的二進制指令集是CPU設計的時候肯定的,是CPU的設計者(ARM公司)定義的,本質上是一串由1和0組成的數字。這就是CPU的彙編指令集

2. 從源代碼到cpu執行過程

第二節 指令集對cpu的意義

1. 彙編語言與C等高級語言的差別

  • 彙編無移植性,c語言有必定可移植性,jave等更高級的語言移植性更強
  • 彙編語言效率最高,C次之,jave等更高級語言效率更低
  • 彙編不適合完成大型複雜的項目,更高級語言更適合完成更大,更復雜的項目

2. 彙編語言的本質

  • 彙編的實質是機器指令(機器碼)的助記符,是一種低級符號語言
  • 機器指令集是一款CPU的編程特徵,是這款CPU的設計者制定的。CPU的內部電路設計就是爲了實現這些指令集的功能。機器指令集就好像CPU的API接口同樣
  • 彙編器的工做是把助記符(如MOV相似人的姓名)翻譯成(101001相似身份證號碼)

3. 彙編語言的發展過程

  • 純機器碼編碼
  • 彙編語言編程
  • c語言編程
  • c++語言編程
  • jave,c#等語言編程
  • 腳本語言編程

4. 總結

  • 彙編語言就是CPU的機器指令集的助記符,是一款CPU的本質特徵
  • 不一樣CPU的機器指令集設計不一樣,所以彙編程序不能在不一樣CPU之間相互移植
  • 使用匯編編程能夠充分發揮CPU的設計特色,因此彙編編程效率最高,所以在操做系統內核中效率極其重要處都須要用匯編處理

第三節 RISC和CISC的區別

1. CISC

  • complex instruction set computer複雜指令集CPUlinux

  • CISC體系的設計理念是用最少的指令來完成任務(譬如計算乘法只須要一條MUL指令便可),所以CISC的CPU自己設計複雜,工藝複雜,但好處是編譯器好設計。CISC出現較早,至今Intel還一直採用CISC設計android

2. RISC

  • Reduced Instruction Set computer精簡指令集CPUnginx

  • RISC的設計理念是讓軟件來完成具體的任務,CPU自己僅提供基本功能指令集。所以RISC CPU的指令集中只有不多的指令,這種設計相對於CISC,CPU的設計和工藝簡單了,可是編譯器的設計變難了c++

3.CPU設計方式發展

  • 早期簡單CPU,指令和功能都頗有限程序員

  • CISC時代--CPU功能擴展依賴於指令集的擴展,實質是CPU內部組合邏輯電路的擴展docker

  • RISC年代--CPU僅提供基礎功能指令(譬如內存與寄存器通訊指令,基本運算與判斷指令等),功能擴展由使用CPU的人利用基礎構架來靈活實現編程

4.RISC與CISC指令數對比

通常典型CISC CPU指令在300條左右
ARM CPU經常使用指令30條左右swift

5.發展趨勢

沒有純粹的RISC或CISC,發展方向是RISC和CISC結合,造成一種介於2者之間的CPU類型c#


第四節 統一編址&獨立編址&哈佛結構&馮諾伊曼結構

1. 統一編址&獨立編址

什麼是IO?什麼是內存?

  • 內存就是程序的運行場所,內存和CPU之間經過總線鏈接,CPU經過必定的地址來訪問具體內存單元安全

  • IO(input and output)是輸入輸出接口,是CPU和其餘外部設備(如串口,LCD,觸摸屏,LED等)之間通訊的道路。通常的,IO就是隻CPU的各類內部和外部外設

內存的訪問方式

  • 內存經過CPU的數據總線來尋址定位,而後經過CPU數據總線來讀寫

  • CPU的地址總線的位數是CPU設計時肯定的,所以一款CPU所能尋址的範圍是必定的,而內存是須要佔用CPU的尋址空間

  • 內存與CPU的這種總線式鏈接方式是一種直接鏈接,優勢是效率高訪問塊,缺點是資源有限,擴展性差

IO的訪問方式(經過訪問寄存器來操做IO)

  • IO指的是與CPU鏈接的各類外設

  • CPU訪問各類外設有2種方式,一種是相似於訪問內存的方式,即把外設的寄存器當作一個內存地址來讀寫,從而以訪問內存相同的方式來操做外設,叫IO與內存統一編址方式(RISC,如ARM);另外一種是使用專用的CPU指令來訪問某種特定外設,叫IO與內存獨立編址(CISC)

內存與IO訪問方式的對比

  • 因爲內存訪問頻率高,所以採用總線式鏈接,直接地址訪問,效率最高

  • IO與內存統一編址方式,優點是IO當作內存來訪問,編程簡單;缺點是IO也須要佔用必定的CPU地址空間,而CPU的地址空間是有限資源

  • IO與內存獨立編址方式,優點是不佔用CPU地址空間;缺點是CPU設計變複雜了

2. 馮諾伊曼結構與哈佛結構

程序和數據

  • 程序運行是兩大核心元素:程序代碼+數據

  • 程序是咱們寫好的源代碼通過編譯,彙編以後獲得的機器碼,這些機器碼能夠拿給CPU去解碼執行,CPU不會去修改程序,因此程序是隻讀的

  • 數據是程序運行過程當中定義和產生的變量的值,是能夠讀寫的,程序運行實際就是爲了改寫數據的值

什麼是馮諾伊曼結構?什麼是哈佛結構?

  • 程序和數據都放在內存中,且不彼此分離的結構稱爲馮諾伊曼結構,譬如Intel的CPU均採用馮諾伊曼結構

  • 程序和內存分開獨立放在不一樣的內存塊中,彼此徹底分離的結構稱爲哈佛結構。譬如大部分單片機(MCS51,ARM9等)均採用哈佛結構

馮諾伊曼結構與哈佛結構對比

  • 馮諾伊曼結構中程序和數據不區分的放在一塊兒,所以安全域穩定性(病毒)是個問題,好處是處理器來簡單

  • 哈佛結構中程序(通常放在ROM,flash中)和數據(通常放在RAM中)獨立分開存放,所以好處是安全和穩定性高,缺點是軟件處理複雜一些(須要統一規劃連接地址等)

第五節 軟件編程控制硬件的關鍵---寄存器

1. 什麼是寄存器

  • 寄存器屬於CPU外設的硬件組成部分
  • CPU能夠像訪問內存同樣訪問寄存器
  • 寄存器是CPU的硬件設計者制定的,目的是留做外設被編程的"活動開關"
  • 正如彙編指令集是CPU的編程接口API同樣,寄存器是外設硬件的軟件編程接口API。使用軟件編程控制某一硬件,其實就是編程讀寫該硬件的寄存器
  • 編程操做寄存器相似於訪問內存
  • 寄存器總每一個bit位都有特定含義,所以編程操做須要位操做
  • 單個寄存器的位寬通常和CPU的位寬同樣,以實現最佳訪問效率

2. 兩類寄存器

  • SoC中有2類寄存器:通用寄存器(和CPU綁定)和SFR(功能已經在設計CPU時就已經肯定好了,不能再改變,已經事先和某個外設綁定好了)
  • 通用寄存器(ARM中有37個)是CPU的組成部分,CPU的不少活動都須要通用寄存器的支持和參與
  • SFR(special function register特殊功能寄存器)不在CPU中,而存在於CPU的外設中,咱們經過訪問外設的SFR來編程操控這個外設,這就是硬件編程控控制的方法

第六節 ARM體系結構總結

1. ARM是RISC架構

  • [ ] 經常使用的ARM彙編指令只有二三十條

  • [ ] ARM是低功耗CPU

  • [ ] ARM的架構很是適合單片機,嵌入式,尤爲是物聯網領域;而服務器等高校性能領域目前主導仍是Intel

2. ARM是統一編址的(IO與內存)

  • [ ] 大部分ARM(M3 M4 M7 M0 ARM9 ARM11 A8 A9等)都是32位架構

  • [ ] 32位ARM CPU支持的內存少於4G,經過CPU地址總線來訪問

  • [ ] SoC中的各類內部外設經過各自的SFR編程訪問,這些SFR的訪問方式相似於訪問普通內存,這叫IO與內存統一編址

3. ARM是哈佛結構的

  1. 常見的ARM(ARM7除外(已淘汰))都是哈佛結構的

  2. 哈佛結構保證了ARM CPU運行的穩定性和安全性,所以ARM適用於嵌入式領域

  3. 哈佛結構也決定了ARM裸機程序(使用實地址即物理地址的地址叫裸機程序)的連接比較麻煩,必須使用複雜的連接腳本告知連接器如何組織程序;對於OS之上的應用(工做在虛擬地址之中)則不需考慮這麼多


第七節 S5PV210的地址映射詳解

1. 什麼是地址映射(通常叫內存映射)

  • S5PV210屬於ARM Cortex-A8架構,32位CPU,CPU設計時就有32根地址線&32根數據線

  • 32根地址線決定了CPU的地址空間爲4G,那麼這4G空間如何分配使用?這個問題就是地址映射問題(硬編碼,不能修改)

2. 一些專用術語

  • ROM:read only memory 只讀存儲器(不能直接經過地址總線和數據總線寫)
  • RAM:ramdom access memory 隨機訪問存儲器
  • IROM:internal rom 內部ROM,指的是集成到SoC內部的ROM(內存條有兩個IROM&IRAM,目的是映射和轉換。底下是上面的映射,很靈活)
  • IRAM:internal ram 內部RAM,指的是集成到SoC內部的RAM
  • DRAM:dynamic ram 動態RAM(外部接的內存就是平時咱們插入的內存條)
  • SRAM:static ram 靜態RAM,容量小,價格高,優勢是不須要軟件初始化直接上電就能用
  • SROM:接網卡

第八節 CPU和外部存儲器的接口

1.內存與外存的區別

  • 內存就是內部存儲器,是用來運行程序的,即RAMDRAM,SRAM,DDR),經過地址總線訪問

  • 外存就是外部存儲器,是用來存儲東西的,即ROM(硬盤,flash(Nand,iNand...U盤,SSD),光盤)

  • CPU鏈接內存和外存的鏈接方式不一樣。內存須要直接地址訪問,因此是經過地址總線和數據總線的總線式訪問方式鏈接到(好處是直接訪問,隨機訪問;壞處是佔用CPU的地址空間,大小受限);外存是經過CPU的外存接口來鏈接到(好處是不佔用CPU的地址空間,壞處是訪問速度沒有總線式快,訪問時序較複雜)

2. SoC經常使用外部存儲器

Flash類(電子式)

  • NorFlash(總線式訪問,接到SROMC Bank,優勢是能夠直接總線訪問,通常用來啓動,太貴,已不多使用,但很可靠)
  • NandFlash(分爲SLC和MLC,已漸漸淘汰)
  • eMMC/iNand/moviNand(iNand是SanDisk公司出廠的eMMC,moviNand是三星出廠的eMMC)
  • oneNAND(oneNand是三星出的一種Nand,只有三星使用)
  • eSSD(e即embeded嵌入式)
  • SD卡/TF卡/MMC卡

硬盤類

SATA硬盤(機械式訪問,磁存儲原理,SATA是接口)

3. X210開發板支持的外部存儲器

  • X210有2個版本,Nand版和iNand版,分別使用NandFlash和iNand位外部存儲器。咱們使用的是iNand版本,板載4GBiNand

  • S5PV210共支持4個SD/MMC通道,其中通道0和2依次用做啓動。X210開發板中SD/MMC0通道用於鏈接板載MMC,所以外部啓動時SD/MMC2通道(注意通道3不能啓動)

第九節 S5PV210的啓動過程詳解

1. S5PV210 的啓動過程

第一步:CPU上電後先從內部iROM中讀取預先設置的代碼,執行。這一段iROM代碼作了一些基本的初始化(CPU時鐘,關看門狗...)(這一段iROM代碼是三星出廠前設置的,三星不知道咱們板子上未來接的是什麼樣的DRAM,所以這一段iROM是不能負責初始化外接的DRAM,所以這一段代碼只能初始化SoC內部的東西);而後這一段代碼會判斷咱們選擇的啓動模式(咱們經過硬件跳線能夠更改板子的啓動模式),而後從相應的外部存儲器去讀取第一部分啓動代碼(BL1,大小爲16KB)到內部SRAM

第二步:從SRAM去運行上一步讀取來的BL1(16KB),而後執行。BL1負責初始化NandFlash,而後將BL2讀取到iRAM(80KB).

第三步:從iRAM運行BL2,BL2初始化DRAM,而後將OS讀取到DRAM中,而後啓動OS,啓動過程結束

思路:由於啓動代碼的大小是不定的,因此兩步啓動不合適
三星的解決方案是:把啓動代碼分爲2半(BL1和BL2),這兩部分協同工做來完成啓動

2. BL0(iROM)作了什麼

  • 關看門狗
  • 初始化指令cache
  • 初始化棧
  • 初始化堆
  • 初始化塊設備複製函數device copy function
  • 設置SoC時鐘系統
  • 複製BL1到內部的iRAM(16KB)
  • 檢查BL1的校驗和
  • 跳轉到BL1去執行

3. S5PV210的全部啓動

  • 先1st,經過OMpin選擇啓動介質
  • 再2nd啓動,從SD2
  • 再Uart啓動
  • 再USB啓動

4. 其餘

  1. 內存:

    SRAM:靜態內存,特色是容量小,價格高,優勢是不須要軟件初始化直接上電就能用
     DRAM:動態內存,特色是容量大,價格低,缺點是上電後不能直接使用,須要軟件初始化後纔可使用

單片機中:內存需求量小,並且但願開發儘可能簡單,適合所有用SRAM
嵌入式系統:內存需求量大,並且沒有NorFlash等可啓動介質
PC機中:內存需求量大,並且軟件複雜,不在意DRAM的初始化開銷,適合所有用DRAM

2 . 外存:

NorFlash:特色是容量小,價格低,優勢是能夠和CPU直接總線式相連,CPU上電後能夠直接讀取,因此通常用啓動介質 NandFlash(跟硬盤同樣):特色是容量大,價格低,缺點是不能總線式訪問,也就是說不能上電CPU直接讀取,須要CPU先運行一些初始化軟件,而後經過時序接口讀寫

因此通常PC機都是:不多容量的BIOS(NorFlash) + 很大容量的硬盤(相似NandFlash) + 大容量的DRAM
通常的單片機:不多容量的NorFlash + 不多容量的SRAM
嵌入式系統:由於NorFlash很貴,如今不少嵌入式系統傾向於不一樣NorFlash,直接用:外接的大容量Nand + 外接大容量DRAM + SoC內置SRAM

3 . S5PV210啓動方式是:外接的大容量Nand + 外接大容量DRAM + SoC內置SRAM
實際上,210內置了一塊96KB的SRAM(叫iRAM),同時還有一塊內置的64KB大小的NorFlash

第十節 如何在開發板上選擇不一樣的啓動方式

  1. 體驗從SD0的eMMC啓動
    開發板默認從eMMC啓動,內部預先燒錄了Android

  2. 從SD2啓動
    可使用外置SD卡從SD2通道啓動,但這須要先破壞板載的eMMC中的android鏡像。破壞方法見《X210V3開發板當即教程》2.5.2節

  3. USB調試模式

第十一節 ARM的編程模式和7種工做模式

1. ARM的基本設定

  1. ARM採用的是32位架構
  2. ARM約定:

    Byte: 8 bits Halfword:16 bits (2 byte) Word: 32 bits (4 byte)
  3. 大部分ARM core提供

    ARM指令集(32 bit) Thumb指令集(16 bit) Thumb2指令集(16 & 32 bit)

4.Jazelle cores 支持 jave bytecode

2. ARM處理器工做模式

  1. ARM處理器共有7種基本工做模式

    用戶模式
     User:非特權模式,大部分任務執行在這種模式 異常模式 FIQ:當一個高優先級(fast)中斷產生時將會進入這種模式 IRQ:當一個低優先級(normal)中斷產生是將會進入這種模式 Supervisor(管理模式):當復位或軟中斷指令執行時將會進入這種模式 Abort:當存取異常時將會進入這種模式 Undef:當執行未定義指令時將會進入這種模式 系統模式 System:使用和User模式相同寄存器集的特權模式

注意:

  1. 除User(用戶模式)是Normal(普通模式)外,其餘6種都是Privilege(特權模式)
  2. Privilege中除sys模式外,其他5種爲異常模式
  3. 各類模式的切換,能夠是程序員經過代碼主動切換(經過寫CPSP寄存器);也能夠是CPU在某些狀況下自動切換
  4. 各類模式下權限和能夠訪問的寄存器不一樣

2. CPU爲何設計這些模式

  1. CPU是硬件,OS是軟件,軟件的設計要依賴硬件的特性,硬件的設計要考慮軟件須要,便於實現軟件特性
  2. 操做系統有安全級別要求,所以CPU設計多種模式是爲了方便操做系統的多種角色安全等級須要

第十二節 ARM的37個寄存器(不是SFG)詳解

1. 概述

ARM總共有37個寄存器,可是每種模式下最多隻能看到18個寄存器,其餘寄存器雖然名字相同可是在當前模式下不可見。

37個寄存器中30個爲"通用」型,1個固定用做PC,一個固定用做CPSR,5個固定用做5中異常模式下的SPSR

對r14這個名字來講,在ARM中共有6個名叫r14(又叫sp)的寄存器,可是在每種特定處理器模式下,只有一個r14是當前可見的,其餘的r14必須切換到它的對應模式下才能看到。這種設計叫影子寄存器(banked register)

2. CPSR程序狀態寄存器

  1. Mode位(0 - 4)

    處理器模式位
  2. T Bit(5)

    僅ARM xT架構支持
     T = 0:處理器處於ARM狀態 T = 1:處理器處於Thumb狀態
  3. 中斷禁止位(6 - 7)

    I = 1:禁止IRQ F = 1:禁止FIQ
  4. J位(24)

    僅ARM 5TE/J架構支持
     J = 1:處理器處於Jazelle狀態
  5. Q位(27)

    僅ARM 5TE/J架構支持
     指示飽和狀態
  6. 條件位(28 - 31)

    N = Negative result from ALU Z = Zero result from ALU C = ALU operation Carried out V = ALU operation overflowed

3. PC(r15)程序控制寄存器

  1. PC(Program control register)爲程序指針,PC指向哪裏,CPU就會執行哪條指令(因此程序跳轉是就是把目標地址代碼放到PC中)
  2. 整個CPU中只有一個PC(CPSR也只有一個,但SPSR有5個)

第十二節 ARM的異常處理方式簡單介紹

1. 什麼是異常

  1. 正常工做以外的流程都叫異常

  2. 異常會打斷正在執行的工做,而且通常我慢但願異常處理完成後繼續回來執行原來的工做

  3. 中斷是異常的一種

2. 異常向量表

  1. 全部的CPU都有異常向量表,這是CPU設計時就設定好的,是硬件決定的

  2. 當異常發生時,CPU會自動動做(PC跳轉到宜昌向量到處理異常,有時伴有一些輔助動做)

  3. 異常向量表是應將想軟件提供的處理異常的支持

3. ARM的異常處理機制

  1. 當異常產生時

    拷貝CPSR到SPSR_<mode> 設置適當的CPSR位: 改變處理器狀態進入ARM態 改變處理器模式進入相應的異常模式 設置中斷禁止位禁止相應中斷 保存返回地址到LR_<mode> 設置PC爲相應的異常向量
  2. 返回時,異常處理須要

    從SPSR_<mode>恢復CPSR 從LR_<mode>恢復PC Note:這些操做只能在ARM態執行

第十三節 ARM的彙編指令集

1. 指令與僞指令的概念

  1. (彙編)指令是CPU機器指令的助記符,通過編譯後會獲得一串10組成的機器碼,能夠由CPU讀取執行

  2. (彙編)僞指令本質上不是指令(只是和指令一塊兒寫在代碼中),他是編譯器環境提供的,目的是用來指導編譯過程,通過編譯後僞指令最終不會生成機器碼

2. 兩種不一樣風格的ARM指令

  1. ARM官方的ARM彙編風格:指令通常用大寫,Windows中IDE開發環境(如ADS,MDK等)經常使用。如:LDR R0,[R1]

  2. GNU風格的ARM彙編:指令通常用小寫字母,linux中經常使用。如ldr r0,[r1]

3. ARM彙編的特色

LDR/STR架構

  1. ARM採用RISC架構,CPU自己不能直接讀取內存,而須要先講內存中的內容加載入CPU中通用寄存器中才能被CPU處理

  2. ldr(load register)指令將內存內容加載入通用寄存器

  3. str(store register)指令將寄存器內容存入內存空間中

  4. ldr/str組合用來實現ARM CPU和內存數據交換

8種尋址方式

> * 寄存器尋址 mov r1,r2 > * 當即尋址 mov r0,#0xFF00 > * 寄存器移位尋址 mov r0,r1,lsl #3 > * 寄存器間接尋址 ldr r1,[r2] > * 基址變址尋址 ldr r1,[r2,#4] > * 多寄存器尋址 ldmia r1!,{r2-r7,r12} > * 堆棧尋址 stmfd sp!,{r2-r7,lr} > * 相對尋址 beq flag 

指令後綴

同一指令常常附帶不一樣後綴,變成不一樣的指令。常用的後綴有

> * B(Byte) 功能不變,操做長度變爲8位 > * H(Half word) 功能不變,長度變爲16位 > * S(Signed) 功能不變,操做數變爲有符號 > * 如ldr ldrb ldrh ldrsb ldrsh > * S(S標誌) 功能不變,影響CPSR標誌位 > * 如mov movs 

條件執行後綴

條件後綴是否成立,不是取決於本句代碼,而是取決於這句代碼以前的代碼運行後的結果
條件後綴決定了本句代碼是否被執行,而不會影響上一句和下一句代碼是否被執行

moveq r0,r1  @相似於c語言中的if (eq) {r0= r1;}
操做碼 條件碼助記符 標誌 含義
0000 EQ Z = 1 相等
0001 NE Z = 0 不相等
0010 CS/HS C = 1 無符號數大於或等於
0011 CC/LO C = 0 無符號數小於
0100 MI N = 1 負數
0101 Pl N = 0 正數或零
0110 VS V = 1 溢出
0111 VC V = 0 沒有溢出
1000 HI C = 1,Z = 0 無符號數大於
1001 LS C = 0,Z = 1 無符號數小於或等於
1010 GE N = V 有符號數大於或等於
1011 LT N != V 有符號數小於
1100 GT Z = 0,N = V 有符號數大於
1101 LE Z = 1,N != V 有符號數小於或等於
1110 AL 任意 無條件執行(指令默認條件)
1111 NV 任意 從不執行(不要使用)

多級指令流水線

爲了增長處理器指令流的速度,ARM使用多級流水線, S5PV210使用13級流水線,ARM11爲8級

容許多個操做同時處理,而非順序執行

PC指向正被取值的指令,而非正在指向的指令

4. 經常使用的ARM指令

數據處理指令

數據傳輸指令 mov mvn
算術指令 add sub rsb adc sbc rsc 邏輯指令 and orr eor bic 比較指令 cmp cmn tst teq 乘法指令 mvl mla umull umlal smull smlal 前導零計數 clz

注意
1 . mvn和mov用法同樣,區別是mov是原封不動的傳遞,而mvn是按位取反後傳遞

mov r1,r2 @兩個寄存器之間數據傳遞 mov r1,#0 @將當即數傳給寄存器

2 . and orr(邏輯或) eor(邏輯異或) bic(位清除指令)

bic r0,r0,#0x1f @將r0中的數的bit0到bit4清零後賦值給r0 0x1f = 0x0000 001f = 0x0000 ```` 11111

3 . 比較指令用來不叫2個寄存器中的數

cmp r0,r1 @比較r0,r1的數是否相等 cmn r0,r1 @讓r0和r1中的數相加 tst r0,#0xf @測試r0的bit0-bit3是否相等

注意:比較指令不用後加s後綴就能夠影響spcr中的標誌位

4 . sub r2,r0,r1 (r2 = r0 -r1)

cpsr訪問指令

CPSR寄存器比較特殊,須要專門的指令訪問,這就是mrs和msr

mrs & msr(更強)

mrs用來讀psr,msr用來寫psr

注意cpsr和spsr的區別和聯繫:
cpsr是程序狀態寄存器,整個SoC中只有1個;而spsr有5個,分別在5中異常模式下,做用是當從普通模式進入一場模式時,用來保存以前普通模式下的cpsr,以在返回普通模式時恢復原來的cpsr

跳轉(分支)指令

b & bl & bx

b 直接跳轉
bl branch and link,跳轉前把返回地址放入lr中,以便返回,以便於函數調用
bx 跳轉同時切換到ARM模式,通常用於異常處理的跳轉(如今已經不用)

訪存指令

ldr/str & ldm/stm &swp

單個字/半字/字節訪問ldr/str
多字批量訪問 ldm/stm
swp r1,r2,[r0] @內存與寄存器交換內容
swp r1,r1,[r0]

軟中斷指令

swi(software interrupt) 

軟中斷指令用來實現操做系統中系統調用

5. ARM彙編中的當即數(標誌符號#)

  1. 合法當即數和非法當即數

  2. ARM指令都是32位,除了指令標記和操做標記外,自己只能附帶不多位數的當即數。所以當即數有合法與非法之分

  3. 合法當即數:通過任意位數的移位後非零部分能夠用8位表示的幾位合法當即數

    合法:0xf000 000f,0x00ff 0000

6. ARM的協處理器指令

什麼是協處理器

  • SoC內部另外一處理核心,協助主CPU實現某些功能,被主CPU調用執行必定任務

  • ARM設計上支持多達16個協處理器,可是通常SoC只實現其中的CP15(coprocessor)

  • 協處理器和MMU,cache,TLB等處理有關,功能上和操做系統1的虛擬地址映射,cache管理等有關

協處理器cp15操做指令

mcr & mrc 

mrc用於讀取cp15中的寄存器
mcr用於寫入cp15中的寄存器

MRC & MCR的使用方法

  • [ ] mcr{
  • [ ] opcode_1:對於cp15永遠爲0
  • [ ] Rd:ARM的普通寄存器
  • [ ] Crn:cp15的寄存器,合法值是c0-c15
  • [ ] Crm:cp15的寄存器,通常均設爲c0
  • [ ] opcode_2:通常省略或爲0

7.ARM的ldm/stm與棧處理

爲何須要多寄存器訪問指令

  • ldr/str每週期只能訪問4字節內存,若是須要批量讀取,寫入內存時太慢,解決方案是ldm/stm
  • ldm/stm:load register multiple/store register multiple
  • 舉例(uboot的start.S 537行)

    stmia sp,{r0-r12} @將r0存入sp指向的內存處(假設爲0x3000 1000);而後地址+4(即指向0x3000 1004),將r1存入該地址;而後地址再+4(指向0x3000 1008),將r2存入該地址.....直到r12內容放入(0x300 1030),指令完成 一個存訪週期同時完成13個寄存器的讀寫 (r0-r12寄存器,sp寄存器裏放了一個內存)

8種後綴

  • ia(increase after)先傳輸,再地址+4
  • ib(increase brfore)先地址+4,再傳輸
  • da(decrease after)先傳輸,再地址-4
  • db
  • fd(full decrease)滿遞減堆棧
  • ed(empty decrease)空遞減堆棧
  • fa 滿遞增堆棧
  • ea 空遞增堆棧

4種棧

  • 空棧:棧指針指向空位,每次存入時能夠直接存入而後棧指針移動一格;而取出時須要先移動一格才能取出
  • 滿棧:棧指針指向棧中最後一個數據,每次存入時須要先移動棧指針一格再存入
  • 增棧:棧指針移動時向地址增長的方向移動的棧
  • 減棧:棧指針移動時向地址減小的方向移動的棧

!的做用

ldmia r0,{r2 - r3} ldmia r0 !,{r2 - r3}

!做用是r0的值在ldm過程當中發生的增長或者減小最後寫回r0的值

^的做用

ldmfd sp!,{r0 - r6,pc} ldmfd sp!,{r0 - r6,pc}^ 

^的做用:在目標寄存器中有PC時,會同時將spsr寫入到cpsr,通常用於從異常模式返回

8. 總結

操做棧時使用相同的後綴就不會出錯
批量讀取或寫入內存時要用ldm/stm指令
經常使用stmfd和stmia

第十四節 ARM彙編僞指令

1. 僞指令的意義

  • 僞指令不是指令,僞指令和指令的根本區別是通過編譯後會不會生成機器碼
  • 僞指令的意義在於指導編譯過程
  • 僞指令是和具體的編譯器相關的,咱們使用gnu工具鏈,所以學習gnu環境下的彙編僞指令

2. gnu彙編中的一些符號

  • [ ] @用來作註釋。能夠在行首也能夠在代碼後面同一行直接跟,和c語言中的//相似
  • [ ] # 作註釋,通常放在行首,表示這一行都是註釋而不是代碼
  • [ ] :以冒號結尾的是標號
  • [ ] .點號在gnu彙編中表示當前指令的地址
  • [ ] #當即數前面要加#或$,表示這個數是當即數

3. 經常使用gnu僞指令

  • [x] .global_start @給_start外部連接屬性
  • [x] .section.text @指定當前段爲代碼段
  • [x] .ascii.byte.short.long.word @定義變量(數據類型)
  • [x] .quad.float.string @定義數據(與上一致·不經常使用)
  • [x] .align 4 @以16字節對齊(2^4)
  • [x] .balignl 16 0xabcdefgh @16字節對齊填充(b表示位填充;align表示對齊;l表示long,以4字節爲單位填充;16表示16字節對齊,0xabcdefgh是用來填充的原料)
  • [x] .equ @相似c語言中的宏定義

4. 偶爾會用到的gnu僞指令

  • [ ] .end @標誌文件結束
  • [ ] .include @頭文件包含
  • [ ] .arm/.code32 @聲明如下爲arm指令
  • [ ] .thumb/.code16 @聲明如下爲thubm指令

5. 最重要的幾個僞指令

  • [x] ldr @大範圍的地址加載指令
  • [x] adr @小範圍的地址加載指令
  • [x] adrl @中等範圍的地址加載指令
  • [x] nop @空操做

ARM中有一個ldr指令,還有一個ldr僞指令

ldr指令:ldr r0,#0xff ldr僞指令:ldr r0,=0xfff1 @涉及到合法/非法當即數,涉及到ARM文字池 

通常都使用ldr僞指令而不用ldr指令

adr和ldr的區別

  • adr編譯時會被一條sub或add指令替代,而ldr編譯時會被一條mov指令替代或者文字池的方式處理
  • adr老是以PC爲基準來表示地址,所以指令自己和運行地址有關,能夠用來檢測程序當前的運行地址在哪裏
  • ldr加載的地址和鏈接式給定的地址有關,由連接腳本決定

adr和ldr的差異:ldr加載的地址在鏈接時肯定,而adr加載的地址在運行是肯定;因此咱們能夠經過adr和lar加載的地址比較來判斷當前程序是否在連接時指定的地址運行(重定位)

注:參考朱老師物聯網大講堂

相關文章
相關標籤/搜索