1 前言
ARM既是一種處理器架構(gòu),也是一家公司,它不生產(chǎn)芯片,只靠芯片IP授權(quán)賺錢。
ARM處理器是英國Acorn有限公司設(shè)計(jì)的低功耗成本的第一款RISC微處理器。全稱為Advanced RISC Machine。ARM處理器本身是32位設(shè)計(jì),但也配備16位指令集,一般來講比等價(jià)32位代碼節(jié)省達(dá)35%,卻能保留32位系統(tǒng)的所有優(yōu)勢。
更多詳細(xì)介紹,請參考百度百科.
2 ARM知識(shí)圖譜
本文先列個(gè)大綱,后續(xù)有時(shí)間再補(bǔ)充。
3 ARM匯編基礎(chǔ)三大塊
這里整理了ARM匯編中非常基礎(chǔ)的三大塊知識(shí),了解了這三大塊內(nèi)容基本可以看懂甚至編譯一些簡單的匯編程序。
3.1 尋址方式
ARM的尋址方式總共有9種,包括:
3.1.1 立即尋址
操作數(shù)是立即數(shù),以“#”為前綴,表示 16 進(jìn)制數(shù)值時(shí)以“0x”表示。
例:
MOV R0,#0xFF00 ;0xFF00 -> R0
SUBS R0,R0,#1 ;R0 – 1 -> R0
3.1.2 寄存器尋址
操作數(shù)的值在寄存器中,指令執(zhí)行時(shí)直接取出寄存器值操作。
例:
MOV R1,R2 ;R2 -> R1
SUB R0,R1,R2 ;R1 - R2 -> R0
3.1.3 寄存器偏移尋址
當(dāng)?shù)诙僮鲾?shù)是寄存器偏移方式時(shí),第二個(gè)寄存器操作數(shù)在與第一個(gè)操作數(shù)結(jié)合之前,選擇進(jìn)行移位操作。
例:
MOV R0,R2,LSL #3 ;R2 的值左移 3 位,結(jié)果放入 R0,即 R0 = R2 * 8
ANDS R1,R1,R2,LSL #3 ;R2 的值左移 3 位,然后和 R1 相與操作,結(jié)果放入 R1
可采用的移位操作:
LSL:邏輯左移(Logical Shift Left),低端空出位補(bǔ) 0
LSR:邏輯右移(Logical Shift Right),高端空出位補(bǔ) 0
ASR:算術(shù)右移(Arithmetic Shift Right),移位過程中符號位不變,即源操作數(shù)為正數(shù),則高端空出位補(bǔ) 0,否則補(bǔ) 1
ROR:循環(huán)右移(Rotate Right),由低端移出位填入高端空出位
RRX:帶擴(kuò)展的循環(huán)右移(Rotate Right eXtended by 1 place),操作數(shù)右移一位,高端空出位用原 C 標(biāo)志值填充。
3.1.4 寄存器間接尋址
操作數(shù)保存在寄存器指定地址的存儲(chǔ)單元中,即寄存器為操作數(shù)的地址指針。
例:
LDR R1,[R2] ;將 R2 中的數(shù)值作為地址,取出此地址中的數(shù)據(jù)保存在 R1 中
SWP R1,R1,[R2] ;將R2中的數(shù)值作為地址,取出此地址中的數(shù)值與 R1 中的值**
3.1.5 基址尋址
將基址寄存器的值與偏移量相加,形成操作數(shù)的有效地址,基址尋址用于訪問基址附近的存儲(chǔ)單元,常用于查表、數(shù)組操作、功能寄存器訪問等。
例:
LDR R2,[R3,#0x0F] ;將R3中的數(shù)值加 0x0F 作為地址,取此地址的值保存在 R2 中
STR R1,[R0,#-2] ;將R0中的數(shù)值減 2 作為地址,把 R1的值保存到此地址中
3.1.6 多寄存器尋址
一次傳送多個(gè)寄存器值,允許一條指令傳送 16 個(gè)寄存器的任何子集或所有寄存器。多寄存器尋址時(shí),寄存器子集按由小到大的順序排列,連續(xù)的寄存器可用“-”連接,否則,用“,”分隔書寫。
例:
LDMIA R1!,{R2-R7,R12} ;將 R1的值讀出到 R2-R7,R12,過程中R1 自動(dòng)加 1
STMIA R0!,{R3-R6,R10};將 R3-R6,R10的值保存到 R0 指向的地址,過程中R0 自動(dòng)加 1
3.1.7 堆棧尋址
堆棧尋址使用堆棧指針SP,即R13,指向堆棧的棧頂。堆??煞譃閮煞N:
向上生長:向高地址方向生長,稱為遞增堆棧,
向下生長:向低地址方向生長,稱為遞減堆棧,
堆棧指針指向最后壓入的有效數(shù)據(jù)項(xiàng),稱為滿堆棧,
堆棧指針指向下一個(gè)要放入的空位置,稱為空堆棧,這樣就有 4 種類型的堆棧。
A)滿遞增:堆棧地址向上增長,堆棧指針指向有效數(shù)據(jù)的最高地址。如 LDMFA,STMFA。
B)空遞增:堆棧地址向上增長,堆棧指針指向堆棧上的第一個(gè)空位置。如 LDMEA,STMEA 。
C)滿遞減:堆棧地址向下增長,堆棧指針指向有效數(shù)據(jù)項(xiàng)的最低地址。如 LDMFD,STMFD。
D)空遞減:堆棧地址向下增長,堆棧指針指向堆棧下的第一個(gè)空位置。如 LDMED,STMED 。
例:
STMFD SP!,{R1-R7,LR} ; 將 R1~R7,LR 入棧。滿遞減堆棧。
LDMFD SP!,{R1-R7,LR} ;數(shù)據(jù)出棧,放入 R1~R7,LR 寄存器。滿遞減堆棧。
3.1.8 塊拷貝尋址
用于將一塊數(shù)據(jù)從存儲(chǔ)器的某一位置拷貝到另一位置。
例:
STMIA R0!,{R1-R7} ;將R1~R7的數(shù)據(jù)保存到存儲(chǔ)器中,存儲(chǔ)器指針在保存第一個(gè)值之后增加,增長方向?yàn)橄蛏显鲩L。
STMIB R0!,{R1-R7} ;將R1~R7的數(shù)據(jù)保存到存儲(chǔ)器中,存儲(chǔ)器指針在保存第一個(gè)值之前增加,增長方向?yàn)橄蛏显鲩L。
STMDA R0!,{R1-R7} ;將R1~R7的數(shù)據(jù)保存到存儲(chǔ)器中,存儲(chǔ)器指針在保存第一個(gè)值之后增加,增長方向?yàn)橄蛳略鲩L。
STMDB R0!,{R1-R7} ;將R1~R7的數(shù)據(jù)保存到存儲(chǔ)器中,存儲(chǔ)器指針在保存第一個(gè)值之前增加,增長方向?yàn)橄蛳略鲩L。
3.1.9 相對尋址
相對尋址是基址尋址的一種變通,由程序計(jì)數(shù)器 PC 提供基準(zhǔn)地址,指令中的地址
碼字段作為偏移量,兩者相加后得到有效地址。
例:
BL ROUTE1 ;調(diào)用ROUTE1 子程序
BEQ LOOP ;條件跳轉(zhuǎn)到 LOOP 標(biāo)號處
…
LOOP MOV R2,#2
…
ROUTE1
…
3.2 寄存器的用途
3.2.1 ARM寄存器列表
ARM共有37個(gè)32位物理寄存器,7種工作模式下可訪問的寄存器見下表,User和System使用完全相同的物理寄存器。
3.2.2 ARM寄存器的用途
其中 r0~r3 主要用于子程序間傳遞參數(shù), r4~r11 主要用于保存局部變量,但在 Thumb 程序中,通常只能使用 r4~r7 來保存局部變量; r12 用作子程序間scratch 寄存器,即 ip 寄存器; r13 通常用做棧指針,即 sp; r14 寄存器又被稱為連接寄存器(lr),用于保存子程序以及中斷的返回地址; r15 用作程序計(jì)數(shù)器(pc),由于 ARM 采用了流水線機(jī)制,當(dāng)正確讀取了 PC 的值后,該值為當(dāng)前指令地址加 8 個(gè)字節(jié),即 PC 指向當(dāng)前指令的下兩條指令地址。
CPSR和SPSR都是程序狀態(tài)寄存器,其中SPSR是用來保存中斷前的CPSR中的值,以便在中斷返回之后恢復(fù)處理器程序狀態(tài)。
3.2.2.1 R0~R7
所有工作模式下,R0-R7都分別指向同一個(gè)物理寄存器(共8個(gè)物理寄存器),它們未被系統(tǒng)用作特殊的用途。在中斷或異常處理進(jìn)行工作模式轉(zhuǎn)換時(shí),由于不同工作模式均使用相同的物理寄存器,可能造成寄存器中數(shù)據(jù)的破壞。
3.2.2.2 R8~R12
在User&System、IRQ、Svc、Abt和Und模式下訪問的R8~R12都是同一個(gè)物理寄存器(共5個(gè)物理寄存器);在FIQ模式下,訪問的R8fiq~R12fiq是另外獨(dú)立的物理寄存器(共5個(gè)物理寄存器)。
3.2.2.3 R13(SP)和R14(LR)
? 在User&System、IRQ、FIQ、Svc、Abt和Und訪問的R13_~R14都是各自模式下獨(dú)立的物理寄存器(共12個(gè)物理寄存器)。
? R13在ARM指令中常用作堆棧指針(SP),但這只是一種習(xí)慣用法,用戶也可使用其他的寄存器作為堆棧指針。而在Thumb指令集中,某些指令強(qiáng)制性的要求使用R13作為堆棧指針。
? 由于處理器的每種工作模式均有自己獨(dú)立的物理寄存器R13,在用戶應(yīng)用程序的初始化部分,一般都要初始化每種模式下的R13,使其指向該工作模式的??臻g。這樣,當(dāng)程序進(jìn)入異常模式時(shí),可以將需要保護(hù)的寄存器放入R13所指向的堆棧,而當(dāng)程序從異常模式返回時(shí),則從對應(yīng)的堆棧中恢復(fù),采用這種方式可以保證異常發(fā)生后程序的正常執(zhí)行。 R14稱為鏈接寄存器(Link Register),當(dāng)執(zhí)行子程序調(diào)用指令(BL)時(shí),R14可得到R15(程序計(jì)數(shù)器PC)的備份。在每一種工作模式下,都可用R14保存子程序的返回地址,當(dāng)用BL或BLX指令調(diào)用子程序時(shí),將PC的當(dāng)前值復(fù)制給R14,執(zhí)行完子程序后,又將R14的值復(fù)制回PC,即可完成子程序的調(diào)用返回。以上的描述可用指令完成。
執(zhí)行以下任意一條指令: MOV PC, LR BX LR 在子程序入口處使用以下指令將R14存入堆棧: STMFD SP!,{,LR} 對應(yīng)的,使用以下指令可以完成子程序返回: LDMFD SP!,{,PC} R14也可作為通用寄存器。
3.2.2.4 程序計(jì)數(shù)器PC(R15)
所有工作模式下訪問的R15都是同一個(gè)物理寄存器,由于ARM體系結(jié)構(gòu)采用了多級流水線技術(shù),對于ARM指令集而言,PC總是指向當(dāng)前指令的下兩條指令的地址,即PC的值為當(dāng)前指令的地址值加8個(gè)字節(jié)。
在ARM狀態(tài)下,R15[1:0]為0,R15[31:2]用于保存PC;在Thumb狀態(tài)下,R15[0]為0,R15[31:1]用于保存PC。
3.2.2.5 CPSR和SPSR
R16用作CPSR(Current Program Status Register,當(dāng)前程序狀態(tài)寄存器),CPSR可在任何工作模式下被訪問,它包括條件標(biāo)志位、中斷禁止位、當(dāng)前處理器模式標(biāo)志位,以及其他一些相關(guān)的控制和狀態(tài)位。
每一種工作模式下又都有一個(gè)專用的物理狀態(tài)寄存器,稱為SPSR(Specified Program Status Register,備份的程序狀態(tài)寄存器),當(dāng)異常發(fā)生時(shí),SPSR用于保存CPSR的當(dāng)前值,從異常退出時(shí)則可由SPSR來恢復(fù)CPSR。 User模式和System模式不屬于異常模式,它們沒有SPSR,當(dāng)在這兩種模式下訪問SPSR,結(jié)果是未知的。
2.6 CPSR各標(biāo)志位含義
31 | 30 | 29 | 28 | 27 | 26 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
N | Z | C | V | Q | DNM(RAZ) | I | F | T | M4 | M3 | M2 | M1 | M0 |
N(Negative)---設(shè)置成當(dāng)前指令運(yùn)算結(jié)果的bit[31]的值。當(dāng)兩個(gè)有符號整數(shù)運(yùn)算時(shí),N=1運(yùn)算結(jié)果為負(fù)數(shù),N=0運(yùn)算結(jié)果為正。
Z(Zero)---Z=1運(yùn)算結(jié)果為零;Z=0表示運(yùn)算的結(jié)果不為零。對于CMP指令,Z=1表示進(jìn)行比較的兩個(gè)數(shù)大小相等。
C(Carried out)---分四種情況討論 1)在加法指令中(包括比較指令CMP),當(dāng)結(jié)果產(chǎn)生進(jìn)位,則C=1,表示無符號運(yùn)算發(fā)生上溢出;其他情況C=0。 2)在減法指令中(包括減法指令CMP),當(dāng)運(yùn)算發(fā)生借位,則C=0,表示無符號運(yùn)算發(fā)生下溢出;其他情況下C=1。 3)對于包含移位操作的非加減運(yùn)算指令,C中包含最后一次溢出的位的數(shù)值 4)對于其他非加減運(yùn)算指令,C位的值通常不受影響 V(oVerflow)---對于加減運(yùn)算指令,當(dāng)操作數(shù)和運(yùn)算結(jié)果為二進(jìn)制的補(bǔ)碼表示的帶符號數(shù)時(shí),V=1符號為溢出;通常其他指令不影響V位。
Q---在ARM V5的E系列處理器中,CPSR的bit[27]稱為Q標(biāo)識(shí)位,主要用于指示增強(qiáng)的DSP指令是否發(fā)生了溢出。同樣的spsr的bit[27]位也稱為Q標(biāo)識(shí)位,用于在異常中斷發(fā)生時(shí)保存和恢復(fù)CPSR中的Q標(biāo)識(shí)位。在ARM V5以前的版本及ARM V5的非E系列的處理器中,Q標(biāo)識(shí)位沒有被定義。
I和F---當(dāng)I=1時(shí)禁止IRQ中斷,當(dāng)F=1時(shí)禁止FIQ中斷
T---對于ARM V4以更高版本的T系列ARM處理器,T=0表示執(zhí)行ARM指令;T=1表示執(zhí)行Thumb指令 對于ARM V5以及更高版本的非T系列處理器,T=0表示執(zhí)行ARM指令;T=1表示強(qiáng)制下一條執(zhí)行的指令產(chǎn)生未定指令中斷
M[4:0]---定義了的ARM工作模式,具體見1中表CSPR[4:0]定義的ARM工作模式
3.3 匯編指令
由于ARM的指令非常多,本文僅列舉常見的一些匯編指令,更多的指令格式,請參考其他資料。
3.3.1 數(shù)據(jù)處理指令
數(shù)據(jù)傳輸指令 mov mvn 算術(shù)指令 add sub rsb adc sbc rsc 邏輯指令 and orr eor bic 比較指令 cmp cmn tst teq 乘法指令 mvl mla umull umlal smull smlal 前導(dǎo)零計(jì)數(shù) clz
3.3.2 cpsr訪問指令
mrs & msr mrs用來讀psr,msr用來寫psr CPSR寄存器比較特殊,需要專門的指令訪問,這就是mrs和msr。
3.3.3 跳轉(zhuǎn)(分支)指令
b & bl & bx b 直接跳轉(zhuǎn)(就沒打開算返回) bl branch and link,跳轉(zhuǎn)前把返回地址放入lr中,以便返回,以便用于函數(shù)調(diào)用 bx跳轉(zhuǎn)同時(shí)切換到ARM模式,一般用于異常處理的跳轉(zhuǎn)。
3.3.4 訪存指令
ldr/str & ldm/stm & swp 單個(gè)字/半字/字節(jié)訪問 ldr/str 多字批量訪問 ldm/stm swp r1, r2, [r0] swp r1, r1, [r0]
3.3.5 軟中斷指令
swi(software interrupt) 軟中斷指令用來實(shí)現(xiàn)OS中系統(tǒng)調(diào)用
4 更多分享
歡迎關(guān)注我的github倉庫01workstation,日常分享一些開發(fā)筆記和項(xiàng)目實(shí)戰(zhàn),歡迎指正問題。
同時(shí)也非常歡迎關(guān)注我的CSDN主頁和專欄:
【CSDN主頁:架構(gòu)師李肯】
【RT-Thread主頁:架構(gòu)師李肯】
【GCC專欄】
【信息安全專欄】
【RT-Thread開發(fā)筆記】
【freeRTOS開發(fā)筆記】
【BLE藍(lán)牙開發(fā)筆記】
【ARM開發(fā)筆記】
【RISC-V開發(fā)筆記】
有問題的話,可以跟我討論,知無不答,謝謝大家。
5 參考鏈接
- ARM尋址方式
- ARM寄存器
- ARM指令
以上參考資料,由本人整理,但來源于網(wǎng)絡(luò),侵刪!
審核編輯:湯梓紅
-
ARM
+關(guān)注
關(guān)注
134文章
9027瀏覽量
366478 -
嵌入式
+關(guān)注
關(guān)注
5059文章
18973瀏覽量
302029 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1261瀏覽量
39838
發(fā)布評論請先 登錄
相關(guān)推薦
評論