第二部分 : 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復雜指令集CPU

  • CISC體系的設計理念是用最少的指令來完成任務(譬如計算乘法只需要一條MUL指令即可),因此CISC的CPU本身設計復雜,工藝復雜,但好處是編譯器好設計。CISC出現較早,至今Intel還一直采用CISC設計

2. RISC

  • Reduced Instruction Set computer精簡指令集CPU

  • RISC的設計理念是讓軟件來完成具體的任務,CPU本身僅提供基本功能指令集。因此RISC CPU的指令集中只有很少的指令,這種設計相對於CISC,CPU的設計和工藝簡單了,但是編譯器的設計變難了

3.CPU設計方式發展

  • 早期簡單CPU,指令和功能都很有限

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

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

4.RISC與CISC指令數對比

一般典型CISC CPU指令在300條左右
ARM CPU常用指令30條左右

5.發展趨勢

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


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

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{ } p15,<opcode_1>, , , ,{<opcode_2>}
  • [ ] 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加載的地址比較來判斷當前程序是否在鏈接時指定的地址運行(重定位)

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM