- 1 . CPU在固定頻率的時鐘控制下節奏運行
- 2 . CPU能夠經過總線讀取外部存儲設備中的二進制指令集,而後解碼執行
- 3 . 這些能夠被CPU解碼執行的二進制指令集是CPU設計的時候肯定的,是CPU的設計者(ARM公司)定義的,本質上是一串由1和0組成的數字。這就是CPU的彙編指令集
- 彙編無移植性,c語言有必定可移植性,jave等更高級的語言移植性更強
- 彙編語言效率最高,C次之,jave等更高級語言效率更低
- 彙編不適合完成大型複雜的項目,更高級語言更適合完成更大,更復雜的項目
- 彙編的實質是機器指令(機器碼)的助記符,是一種低級符號語言
- 機器指令集是一款CPU的編程特徵,是這款CPU的設計者制定的。CPU的內部電路設計就是爲了實現這些指令集的功能。機器指令集就好像CPU的API接口同樣
- 彙編器的工做是把助記符(如MOV相似人的姓名)翻譯成(101001相似身份證號碼)
- 純機器碼編碼
- 彙編語言編程
- c語言編程
- c++語言編程
- jave,c#等語言編程
- 腳本語言編程
- 彙編語言就是CPU的機器指令集的助記符,是一款CPU的本質特徵
- 不一樣CPU的機器指令集設計不一樣,所以彙編程序不能在不一樣CPU之間相互移植
- 使用匯編編程能夠充分發揮CPU的設計特色,因此彙編編程效率最高,所以在操做系統內核中效率極其重要處都須要用匯編處理
complex instruction set computer複雜指令集CPUlinux
CISC體系的設計理念是用最少的指令來完成任務(譬如計算乘法只須要一條MUL指令便可),所以CISC的CPU自己設計複雜,工藝複雜,但好處是編譯器好設計。CISC出現較早,至今Intel還一直採用CISC設計android
Reduced Instruction Set computer精簡指令集CPUnginx
RISC的設計理念是讓軟件來完成具體的任務,CPU自己僅提供基本功能指令集。所以RISC CPU的指令集中只有不多的指令,這種設計相對於CISC,CPU的設計和工藝簡單了,可是編譯器的設計變難了c++
早期簡單CPU,指令和功能都頗有限程序員
CISC時代--CPU功能擴展依賴於指令集的擴展,實質是CPU內部組合邏輯電路的擴展docker
RISC年代--CPU僅提供基礎功能指令(譬如內存與寄存器通訊指令,基本運算與判斷指令等),功能擴展由使用CPU的人利用基礎構架來靈活實現編程
通常典型CISC CPU指令在300條左右
ARM CPU經常使用指令30條左右swift
沒有純粹的RISC或CISC,發展方向是RISC和CISC結合,造成一種介於2者之間的CPU類型c#
內存就是程序的運行場所,內存和CPU之間經過總線鏈接,CPU經過必定的地址來訪問具體內存單元安全
IO(input and output)是輸入輸出接口,是CPU和其餘外部設備(如串口,LCD,觸摸屏,LED等)之間通訊的道路。通常的,IO就是隻CPU的各類內部和外部外設
內存經過CPU的數據總線來尋址定位,而後經過CPU數據總線來讀寫
CPU的地址總線的位數是CPU設計時肯定的,所以一款CPU所能尋址的範圍是必定的,而內存是須要佔用CPU的尋址空間
內存與CPU的這種總線式鏈接方式是一種直接鏈接,優勢是效率高訪問塊,缺點是資源有限,擴展性差
IO指的是與CPU鏈接的各類外設
CPU訪問各類外設有2種方式,一種是相似於訪問內存的方式,即把外設的寄存器當作一個內存地址來讀寫,從而以訪問內存相同的方式來操做外設,叫IO與內存統一編址方式(RISC,如ARM);另外一種是使用專用的CPU指令來訪問某種特定外設,叫IO與內存獨立編址(CISC)
因爲內存訪問頻率高,所以採用總線式鏈接,直接地址訪問,效率最高
IO與內存統一編址方式,優點是IO當作內存來訪問,編程簡單;缺點是IO也須要佔用必定的CPU地址空間,而CPU的地址空間是有限資源
IO與內存獨立編址方式,優點是不佔用CPU地址空間;缺點是CPU設計變複雜了
程序運行是兩大核心元素:程序代碼+數據
程序是咱們寫好的源代碼通過編譯,彙編以後獲得的機器碼,這些機器碼能夠拿給CPU去解碼執行,CPU不會去修改程序,因此程序是隻讀的
數據是程序運行過程當中定義和產生的變量的值,是能夠讀寫的,程序運行實際就是爲了改寫數據的值
程序和數據都放在內存中,且不彼此分離的結構稱爲馮諾伊曼結構,譬如Intel的CPU均採用馮諾伊曼結構
程序和內存分開獨立放在不一樣的內存塊中,彼此徹底分離的結構稱爲哈佛結構。譬如大部分單片機(MCS51,ARM9等)均採用哈佛結構
馮諾伊曼結構中程序和數據不區分的放在一塊兒,所以安全域穩定性(病毒)是個問題,好處是處理器來簡單
哈佛結構中程序(通常放在ROM,flash中)和數據(通常放在RAM中)獨立分開存放,所以好處是安全和穩定性高,缺點是軟件處理複雜一些(須要統一規劃連接地址等)
- 寄存器屬於CPU外設的硬件組成部分
- CPU能夠像訪問內存同樣訪問寄存器
- 寄存器是CPU的硬件設計者制定的,目的是留做外設被編程的"活動開關"
- 正如彙編指令集是CPU的編程接口API同樣,寄存器是外設硬件的軟件編程接口API。使用軟件編程控制某一硬件,其實就是編程讀寫該硬件的寄存器
[ ] 經常使用的ARM彙編指令只有二三十條
[ ] ARM是低功耗CPU
[ ] ARM的架構很是適合單片機,嵌入式,尤爲是物聯網領域;而服務器等高校性能領域目前主導仍是Intel
[ ] 大部分ARM(M3 M4 M7 M0 ARM9 ARM11 A8 A9等)都是32位架構
[ ] 32位ARM CPU支持的內存少於4G,經過CPU地址總線來訪問
[ ] SoC中的各類內部外設經過各自的SFR編程訪問,這些SFR的訪問方式相似於訪問普通內存,這叫IO與內存統一編址
常見的ARM(ARM7除外(已淘汰))都是哈佛結構的
哈佛結構保證了ARM CPU運行的穩定性和安全性,所以ARM適用於嵌入式領域
哈佛結構也決定了ARM裸機程序(使用實地址即物理地址的地址叫裸機程序)的連接比較麻煩,必須使用複雜的連接腳本告知連接器如何組織程序;對於OS之上的應用(工做在虛擬地址之中)則不需考慮這麼多
S5PV210屬於ARM Cortex-A8架構,32位CPU,CPU設計時就有32根地址線&32根數據線
32根地址線決定了CPU的地址空間爲4G,那麼這4G空間如何分配使用?這個問題就是地址映射問題(硬編碼,不能修改)
- 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:接網卡
內存就是內部存儲器,是用來運行程序的,即RAMDRAM,SRAM,DDR),經過地址總線訪問
外存就是外部存儲器,是用來存儲東西的,即ROM(硬盤,flash(Nand,iNand...U盤,SSD),光盤)
CPU鏈接內存和外存的鏈接方式不一樣。內存須要直接地址訪問,因此是經過地址總線和數據總線的總線式訪問方式鏈接到(好處是直接訪問,隨機訪問;壞處是佔用CPU的地址空間,大小受限);外存是經過CPU的外存接口來鏈接到(好處是不佔用CPU的地址空間,壞處是訪問速度沒有總線式快,訪問時序較複雜)
- 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是接口)
X210有2個版本,Nand版和iNand版,分別使用NandFlash和iNand位外部存儲器。咱們使用的是iNand版本,板載4GBiNand
S5PV210共支持4個SD/MMC通道,其中通道0和2依次用做啓動。X210開發板中SD/MMC0通道用於鏈接板載MMC,所以外部啓動時SD/MMC2通道(注意通道3不能啓動)
第一步: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),這兩部分協同工做來完成啓動
- 關看門狗
- 初始化指令cache
- 初始化棧
- 初始化堆
- 初始化塊設備複製函數device copy function
- 設置SoC時鐘系統
- 複製BL1到內部的iRAM(16KB)
- 檢查BL1的校驗和
- 跳轉到BL1去執行
- 先1st,經過OMpin選擇啓動介質
- 再2nd啓動,從SD2
- 再Uart啓動
- 再USB啓動
內存:
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
體驗從SD0的eMMC啓動
開發板默認從eMMC啓動,內部預先燒錄了Android
從SD2啓動
可使用外置SD卡從SD2通道啓動,但這須要先破壞板載的eMMC中的android鏡像。破壞方法見《X210V3開發板當即教程》2.5.2節
USB調試模式
ARM約定:
Byte: 8 bits Halfword:16 bits (2 byte) Word: 32 bits (4 byte)
大部分ARM core提供
ARM指令集(32 bit) Thumb指令集(16 bit) Thumb2指令集(16 & 32 bit)
4.Jazelle cores 支持 jave bytecode
ARM處理器共有7種基本工做模式
用戶模式
User:非特權模式,大部分任務執行在這種模式 異常模式 FIQ:當一個高優先級(fast)中斷產生時將會進入這種模式 IRQ:當一個低優先級(normal)中斷產生是將會進入這種模式 Supervisor(管理模式):當復位或軟中斷指令執行時將會進入這種模式 Abort:當存取異常時將會進入這種模式 Undef:當執行未定義指令時將會進入這種模式 系統模式 System:使用和User模式相同寄存器集的特權模式
注意:
ARM總共有37個寄存器,可是每種模式下最多隻能看到18個寄存器,其餘寄存器雖然名字相同可是在當前模式下不可見。
37個寄存器中30個爲"通用」型,1個固定用做PC,一個固定用做CPSR,5個固定用做5中異常模式下的SPSR
對r14這個名字來講,在ARM中共有6個名叫r14(又叫sp)的寄存器,可是在每種特定處理器模式下,只有一個r14是當前可見的,其餘的r14必須切換到它的對應模式下才能看到。這種設計叫影子寄存器(banked register)
Mode位(0 - 4)
處理器模式位
T Bit(5)
僅ARM xT架構支持
T = 0:處理器處於ARM狀態 T = 1:處理器處於Thumb狀態
中斷禁止位(6 - 7)
I = 1:禁止IRQ F = 1:禁止FIQ
J位(24)
僅ARM 5TE/J架構支持 J = 1:處理器處於Jazelle狀態
Q位(27)
僅ARM 5TE/J架構支持 指示飽和狀態
條件位(28 - 31)
N = Negative result from ALU Z = Zero result from ALU C = ALU operation Carried out V = ALU operation overflowed
正常工做以外的流程都叫異常
異常會打斷正在執行的工做,而且通常我慢但願異常處理完成後繼續回來執行原來的工做
中斷是異常的一種
全部的CPU都有異常向量表,這是CPU設計時就設定好的,是硬件決定的
當異常發生時,CPU會自動動做(PC跳轉到宜昌向量到處理異常,有時伴有一些輔助動做)
異常向量表是應將想軟件提供的處理異常的支持
當異常產生時
拷貝CPSR到SPSR_<mode> 設置適當的CPSR位: 改變處理器狀態進入ARM態 改變處理器模式進入相應的異常模式 設置中斷禁止位禁止相應中斷 保存返回地址到LR_<mode> 設置PC爲相應的異常向量
返回時,異常處理須要
從SPSR_<mode>恢復CPSR 從LR_<mode>恢復PC Note:這些操做只能在ARM態執行
(彙編)指令是CPU機器指令的助記符,通過編譯後會獲得一串10組成的機器碼,能夠由CPU讀取執行
(彙編)僞指令本質上不是指令(只是和指令一塊兒寫在代碼中),他是編譯器環境提供的,目的是用來指導編譯過程,通過編譯後僞指令最終不會生成機器碼
ARM官方的ARM彙編風格:指令通常用大寫,Windows中IDE開發環境(如ADS,MDK等)經常使用。如:LDR R0,[R1]
GNU風格的ARM彙編:指令通常用小寫字母,linux中經常使用。如ldr r0,[r1]
ARM採用RISC架構,CPU自己不能直接讀取內存,而須要先講內存中的內容加載入CPU中通用寄存器中才能被CPU處理
ldr(load register)指令將內存內容加載入通用寄存器
str(store register)指令將寄存器內容存入內存空間中
ldr/str組合用來實現ARM CPU和內存數據交換
> * 寄存器尋址 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指向正被取值的指令,而非正在指向的指令
數據傳輸指令 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寄存器比較特殊,須要專門的指令訪問,這就是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)
軟中斷指令用來實現操做系統中系統調用
合法當即數和非法當即數
ARM指令都是32位,除了指令標記和操做標記外,自己只能附帶不多位數的當即數。所以當即數有合法與非法之分
合法當即數:通過任意位數的移位後非零部分能夠用8位表示的幾位合法當即數
合法:0xf000 000f,0x00ff 0000
SoC內部另外一處理核心,協助主CPU實現某些功能,被主CPU調用執行必定任務
ARM設計上支持多達16個協處理器,可是通常SoC只實現其中的CP15(coprocessor)
協處理器和MMU,cache,TLB等處理有關,功能上和操做系統1的虛擬地址映射,cache管理等有關
mcr & mrc
mrc用於讀取cp15中的寄存器
mcr用於寫入cp15中的寄存器
舉例(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寄存器裏放了一個內存)
- ia(increase after)先傳輸,再地址+4
- ib(increase brfore)先地址+4,再傳輸
- da(decrease after)先傳輸,再地址-4
- db
- fd(full decrease)滿遞減堆棧
- ed(empty decrease)空遞減堆棧
- fa 滿遞增堆棧
- ea 空遞增堆棧
ldmia r0,{r2 - r3} ldmia r0 !,{r2 - r3}
!做用是r0的值在ldm過程當中發生的增長或者減小最後寫回r0的值
ldmfd sp!,{r0 - r6,pc} ldmfd sp!,{r0 - r6,pc}^
^的做用:在目標寄存器中有PC時,會同時將spsr寫入到cpsr,通常用於從異常模式返回
操做棧時使用相同的後綴就不會出錯
批量讀取或寫入內存時要用ldm/stm指令
經常使用stmfd和stmia
ARM中有一個ldr指令,還有一個ldr僞指令
ldr指令:ldr r0,#0xff ldr僞指令:ldr r0,=0xfff1 @涉及到合法/非法當即數,涉及到ARM文字池
通常都使用ldr僞指令而不用ldr指令
adr和ldr的差異:ldr加載的地址在鏈接時肯定,而adr加載的地址在運行是肯定;因此咱們能夠經過adr和lar加載的地址比較來判斷當前程序是否在連接時指定的地址運行(重定位)
注:參考朱老師物聯網大講堂