ARM體系相關知識集錦
從源代碼到cpu的執行過程?
答.c等高級語言源代碼---------->.S匯編文件---------->.elf格式的二進制可執行程序---------->.bin格式的燒錄文件---------->CPU取址,譯碼,執行(流水線)
匯編語言的本質?
答:cpu機器指令集(機器碼)的助記符,是一款cpu的本質特征。不同的cpu機器指令集設計不同,因此匯編指令不能在不同的cpu之間互相移植。也因此,理論上來說用機器指令集來操作cpu是效率最高的。但是現在沒人這么寫代碼了,所以目前來說匯編指令能最大程度發揮硬件性能,之后才輪到c語言,再之后才是上層語言比如c++,java,c#
CISC和RISC架構的特點和區別?
- CISC:設計理念:提供更多的指令集(300條左右),希望用最少的指令完成任務。
缺點:CPU工藝復雜,功耗高。 優點:編譯器容易設計 intel公司至今在用
- RISC:設計理念:只提供基本功能指令集(30條左右),其他功能通過基礎指令集實現。
缺點:編譯器設計復雜 優點:CPU設計簡單,功耗低 ARM公司在用
現在的發展方向是二者均往中間發展,RISC是為了提高性能,CISC是為了降低功耗。
IO與內存統一編址和IO與內存獨立編址?
答:CPU設計的時候地址總線的位數已經確定。內存通過cpu的地址來尋址定位,然后通過cpu數據總線來讀寫。
CPU訪問外設有兩種方式:1.像訪問內存一樣訪問外設,把寄存器當作內存地址一樣來讀寫,叫做IO與內存統一編址
2.使用專用的CPU指令來訪問某種特定外設,叫做IO與內存獨立編址
什么是地址映射?
答:我們的dram本身每個字節是不具備地址的,當我們插入內存條的時候,內存條上的內存會按照預先設定的規則,進行地址映射,這樣就可以訪問了。
什么是馮諾依曼結構?什么是哈佛結構?
答:馮諾依曼結構:程序和代碼都放在內存中,且彼此不分離的結構。 譬如intel的cpu
馮諾依曼結構因為數據和程序不區分的放在一起,所以安全和穩定性是一個問題。但是這樣做處理起來簡單。(程序工作在虛擬地址)
哈佛結構:分開存放程序(一般放在ROM中)和數據(一般放在RAM中)。 譬如大部分的單片機、ARM9等(除ARM7外)均采用哈佛結構
哈佛結構:程序和數據分開存放,所以安全和穩定性高,但是軟件處理會相對復雜。哈佛結構決定了ARM裸機程序(使用物理地址)鏈接的時候比較
麻煩,必須使用復雜的鏈接腳本告知連接器如何組織程序。
intel和arm的對比?
答:intel:CISC架構 + IO與內存統一編址 + 馮諾依曼結構 高性能高功耗,適用於pc機
arm: RISC架構 + IO 與內存統一編址 + 哈佛結構 低功耗,穩定性高,適用於嵌入式開發
一些專業術語?
ROM RAM IROM IRAM DRAM SRAM
Norflash:可以總線式訪問。上電不需要初始化。
后面的必須接口和時序訪問:
NandFlash:分為SLC、MLC,前者穩定,貴。后者便宜,不穩定,必須加校驗。
eMMC/iNand/moviNand oneNand(用的不多,貴,只有三星用) SD卡/TF卡/MMC卡 eSSD
SATA硬盤
s5pv210的啟動過程?
答:s5pv210:內存:SRAM(上電就可運行)、DRAM(需初始化才能運行)
外存:Norflash(上電直接運行) Nandflash(需要初始化才能運行)
- SRAM從iROM中讀取64KB運行,這段代碼:1關看門狗+2初始化cache+3初始化棧+4初始化堆+5初始化設備復制函數+6設置時鍾+7復制BL1到iROM16KB +8檢查BL1校驗和+9是否安全啟動+10跳轉到BL1
- 執行BL1(16KB)即初始化Nandflash--------->接着,加載BL2(80KB)到SRAM,即初始化DRAM
- 將從Nandflash中讀取OS讀取到DRAM中執行。
ARM的基本設定有哪些?
答:Byte:8bits Halfword: 16bit word: 32bit
arm有幾種工作狀態?
答:ARM狀態、Thumb狀態、Jazelle狀態
arm處理器的工作模式有哪些?
答:非特權模式:user模式
特權模式:異常模式:fiq irq svc (reset /swi產生) abort undef
非異常模式:system mointor
arm一共有多少個寄存器?
答:在cortex-a之前一直都是37個寄存器,在cortex-a9出來之后變成了40個,多了一個mointer模式,所以多了3個私有寄存器。
下面顯示的是37個寄存器的情況。
什么是CPU的異常處理機制?
答:當異常發生時,一定是arm狀態,只有arm狀態下有異常
- 異常處理流程:
1.保存cpsr到spsr中
2.設置cpsr 位---------->(1)切換當前狀態位arm狀態(T = 0)
----------->(2)設置相應的異常模式(M[4:0]位)
----------->(3)設置相應中斷禁止位(I=1,F=1)
3.設置程序返回地址(lr_<mode> = pc)
4.設置pc為相應的異常向量
- 返回時:
1.從spsr_<mode>恢復cpsr
2.從lr_<mode>恢復pc(下一條指令)
什么是流水線?
答:cpu執行代碼,會分為3個步驟,取址,譯碼,執行。一條指令需要分為3個周期完成,而且每個周期只能執行一次取址,因為pc指針只有一個,所以,可以將他們錯開執行,這樣可以最大效率的提升cpu執行代碼的效率。但是引發的問題是pc指針指向的是執行代碼的后兩條指令。也就是說在ARM中pc = pc+8; 在thumb中pc= pc+4;
- 影響流水線效率的因素:1.分支 2.互鎖
上一條指令的結果作為下一條指令的參數
分支會清空流水線
mov r1, #2 ; r1 = 2
mov r0, #1 ; r0 = 1
add r2, r1 ; r2 = r1 + r2
由於流水線的存在。所以當遇到這種第三條指令依賴前面兩條指令的執行結果才能運行的情況,由於,必須等待前面兩條執行完成,所以不可以直接對第三條指令取址,所以此時會清空流水線。這樣小路會降低。一個較好的解決方法是吧無關代碼插入到第二句和第三句話之間。
什么是指令?什么是偽指令?
答:(匯編)指令是CPU機器指令的助記符,經過編譯后最終生成一串機器碼,可以由CPU讀取執行
(匯編)偽指令本質上不是指令(只不過和指令一起寫在代碼中),目的是指導編譯過程,經過編譯后不會生成機器碼。
兩種不同風格的ARM指令?
ARM官方匯編風格:指令一般大寫。如 LDR R0, [R1]
GNU風格的ARM匯編:指令一般用小寫字母,linux下常用。 ldr,r0,[r1]
ARM匯編特點?
CPU本身不能讀取內存,需要先將內存中內容載入cpu寄存器中
ldr (load register)指令將內存內容加載到通用寄存器中
str(store register)指令將寄存器內容存入內存空間中
ldr/str組合用來實現ARM CPU和內存數據交換
ARM匯編8種尋址方式?
寄存器尋址 mov r1,r2 //r1=r2
立即尋址 mov r0,#0xff00 //r0=0xff00
寄存器移位尋址 mov r0,r1,lsl #3 //r0=r1<<3,也相當於r0=r1*8
寄存器間接尋址 ldr r1,[r2] //r1= *r2
基址變址尋址 ldr r1, [r2, #4] //r1=*(r2+4)
多寄存器尋址 ldmia r1!,{r2-r7,r12} //r1=r2,r2=r3,r3=r4,r4=r5,r5=r6,r6=r7,r7=r12
堆棧尋址 stmfd sp!,{r2-r7,lr} //上面和這個就是堆棧操作
相對尋址 beq flag //如果此時Z標志位是1那么久執行b flag
什么是指令后綴?
答:b(操作長度變為8) h(長度變為16) s(操作數變為有符號數) s(影響CPSR標志位)
常見的ARM指令?
答:數據傳輸指令:mov mvn 算術指令:add (add r0,r0,r1) sub rsb adc sbc rsc
邏輯指令:and orr(orr r0,r0,0xd3) eor bic(bic r0,r0,#0x1f)
比較指令:cmp(cmp r0,r1 @如果r0=r1,則Z位置1) cmn (cmn r0,r1 @判斷r0r1是否互為相反數)
tst(tst r0,#0x8 @測試bit3是否為1) teq(teq r1,r2 @相等為真)
乘法指令:mvl mla umull umlal smull smlal 前導零計數:clz
cpsr訪問指令?
答: mrs :讀取psr內容 mrs r0,cpsr @r0=cpsr
msr:寫入psr msr cpsr,r0 @cpsr=r0
跳轉指令?
b :直接跳轉,不返回 bl:跳轉前保存返回地址,然后跳轉
bx:跳轉的同時切換狀態(奇數則切換到Thumb狀態,偶數為ARM狀態)現在一般直接在arm模式下寫代碼所以這條指令基本不用了。
8種后綴?
ia:先傳輸,再地址+4 ib:先地址+4再傳輸 da:先傳輸再地址-4 db:先地址-4再傳輸
fd:滿遞增堆棧 ea:空遞增堆棧
匯編中的一些符號?
@注釋 #注釋 :以冒號結尾的是標號 .點號代表當前地址 #立即數前面要加#或者加$
.global _start .section.text .ascii .byte .short .long .word .quad .float .string .align 4(以2的4次方對齊) .equ相當於宏定義
.end .include .arm/.code32(聲明以下是arm指令) .thumb/.code16(聲明以下為thumb指令)
ldr(大范圍的地址加載) adr(小范圍的地址加載) adrl(中等范圍的地址加載指令) nop(空操作)