ARM匯編指令詳解1
Code Warrior IDE提供了一個(gè)簡(jiǎn)單通用的圖形化用戶(hù)界面用于管理項目??梢砸訟RM處理器為對象,利用CodeWarrior IDE開(kāi)發(fā)C、C++和ARM匯編代碼。
AXD是ADS軟件中獨立于CodeWarrior IDE的圖形軟件,AXD用于對程序進(jìn)行調試。(和Jlink一起使用)
工作狀態(tài)
從編程的角度看,ARM微處理器的工作狀態(tài)一般有兩種,并可在兩種狀態(tài)之間切換:
- ARM狀態(tài),此時(shí)處理器執行的是32位的字對齊的ARM指令。
- Thumb狀態(tài),此時(shí)處理器執行的是16位半字對齊的Thumb指令。
在程序執行過(guò)程中,微處理器可以隨時(shí)在兩種工作狀態(tài)之間切換,并且,處理器工作狀態(tài)的轉變并不影響處理器的工作模式和相應寄存器中的內容。
存儲器格式
ARM體系結構將存儲器看作是從零地址開(kāi)始的字節的線(xiàn)性組合。從零字節到三字節放置第一個(gè)存儲的字(32位)數據,從第四個(gè)字節到第七個(gè)字節放置第二個(gè)存儲的字數據,依次排列。作為32位的微處理器,ARM體系結構所支持的最大尋址空間是4G。
ARM體系結構可以用兩種方式來(lái)存儲字數據,稱(chēng)之為大端格式和小端格式。
- 大端格式:字數據的高字節存儲在低地址上,而低字節存儲在高地址上。
- 小端格式:字數據的高字節存儲在高地址上,而低字節存儲在低地址上。
ARM微處理器的指令長(cháng)度可以是32位(在A(yíng)RM狀態(tài)下),也可以為16位(在Thumb狀態(tài)下)。ARM微處理器中支持字節(8位)、半字(16位)、字(32位)三種數據類(lèi)型,
ARM支持7中工作模式,分別為:
1、用戶(hù)模式(Usr):用于正常執行程序
2、快速中斷模式(FIQ):用于高速數據傳輸
3、外部中斷模式(IRQ):用于通常的中斷處理
4、管理模式(svc):操作系統使用的保護模式
5、數據訪(fǎng)問(wèn)終止模式(abt):當數據或指令預取終止時(shí)進(jìn)入該模式,可用于虛擬存儲及存儲保護。
6、系統模式(sys):運行具有特權的操作系統任務(wù)。
7、未定義指令中止模式(und):當未定義的指令執行時(shí)進(jìn)入該模式,可用于支持硬件
ARM微處理器的工作模式可以通過(guò)軟件改變,也可以通過(guò)外部中斷或異常處理改變。應用程序運行在用戶(hù)模式下,當處理器運行在用戶(hù)模式下時(shí),某些被保護的系統資源是不能被訪(fǎng)問(wèn)的。
除用戶(hù)模式以外,其余六種模式稱(chēng)為非用戶(hù)模式或特權模式;其中除用戶(hù)模式和系統模式外的5種又稱(chēng)為異常模式,常用于處理中斷或異常,以及需要訪(fǎng)問(wèn)受保護的系統資源等情況。
ARM的寄存器
ARM微處理器共有37個(gè)32位寄存器,其中31個(gè)通用寄存器,6個(gè)為狀態(tài)寄存器。但是這些寄存器不能被同時(shí)訪(fǎng)問(wèn),具體哪些寄存器可以訪(fǎng)問(wèn),取決于A(yíng)RM工作狀態(tài)及具體的運行模式。但在任何時(shí)候,通用寄存器R14-R0、程序計數器PC、一個(gè)狀態(tài)寄存器都是可以訪(fǎng)問(wèn)的。
寄存器(ARM狀態(tài)):在A(yíng)RM工作狀態(tài)下,任一時(shí)刻可以訪(fǎng)問(wèn)16個(gè)通用寄存器和一到兩個(gè)狀態(tài)寄存器。在非用戶(hù)模式下(特權模式)下,則可訪(fǎng)問(wèn)到特定模式分組寄存器,具體見(jiàn)圖:
寄存器(Thumb狀態(tài)):是ARM狀態(tài)下寄存器集的一個(gè)子集,程序可以直接訪(fǎng)問(wèn)8個(gè)通用寄存器(R7-R0)、程序計數器(PC)、堆棧指針(SP)、連接寄存器(LR)和CPSR。具體見(jiàn)下頁(yè)圖:
Thumb狀態(tài)下的寄存器組織與ARM狀態(tài)下的寄存器組織的關(guān)系:
- Thumb狀態(tài)下和ARM狀態(tài)下的R0-R7是相同的。
- Thumb狀態(tài)下和ARM狀態(tài)下的CPSR和SPSR是相同的。
- Thumb狀態(tài)下的SP對應于A(yíng)RM狀態(tài)下的R13。
- Thumb狀態(tài)下的LR對應于A(yíng)RM狀態(tài)下的R14。
- Thumb狀態(tài)下的程序計數器PC對應于A(yíng)RM狀態(tài)下R15。
不分組寄存器(The unbanked registers)
R0—R7
分組寄存器(The banked registers)
R8—R14
程序計數器:
R15(PC)
- R0-R7是不分組寄存器。這意味著(zhù)在所有處理器模式下,訪(fǎng)問(wèn)的都是同一個(gè)物理寄存器。未分組寄存器沒(méi)有被系統用于特別的用途,任何可采用通用寄存器的應用場(chǎng)合都可以使用未分組寄存器。
- 分組寄存器R8-R12
- 分組寄存器R13、R14.
R13通常用做堆棧指針SP,R14用作子程序鏈接寄存器,指向函數的返回地址。 - R15是程序計數器,也稱(chēng)為PC。其值等于當前正在執行的指令的地址+8(因為在取址和執行之間多了一個(gè)譯碼的階段)。
狀態(tài)寄存器:
ARM所有工作模式下都可以訪(fǎng)問(wèn)程序狀態(tài)寄存器CPSR。CPSR包含條件碼標志、中斷禁止位、當前處理器模式以及其它狀態(tài)和控制信息。CPSR在每種異常模式下都有一個(gè)對應的物理寄存器—程序狀態(tài)保存寄存器SPSR。當異常出現時(shí),SPSR用于保存CPSR的值,以便異常返回后恢復異常發(fā)生時(shí)的工作狀態(tài)。
ARM的尋址方式:
所謂尋址方式就是處理器根據指令中給出的地址信息來(lái)尋找物理地址的方式。
立即尋址:操作數本身就在指令中給出。
ADD R0, R0,#1
ADDR0,R0,#0x3f
第二個(gè)源操作數即為立即數,要求以“#”為前綴。
寄存器尋址:利用寄存器中的數值作為操作數。
ADDR0,R1,R2
寄存器間接尋址:以寄存器中的值作為操作數的地址,而操作數本身存放在存儲器中。
ADDR0,R1,[R2]
LDR
基址變址尋址:將寄存器(該寄存器一般稱(chēng)為基址寄存器)的內容與指令中的給出的地址偏移量相加,從而得到一個(gè)操作數的有效地址。
LDRR0,[R1,#4]
LDRR0,[R1,#4]!
LDR R0,[R1],#4
LDR R0, [R1,R2]
多寄存器尋址:一條指令可以完成多個(gè)寄存器值的傳送。最多實(shí)現16個(gè)通用寄存器值得傳送。
LDMIAR0,{R1,R2,R3,R4}
該指令的后綴IA表示在每次執行完加載后,R0按字長(cháng)增加,因此,指令可將連續存儲單元的值傳送到R1 -R4。
相對尋址:以程序計數器PC的當前值為基地址,指令中的地址標號作為偏移量,將兩者相加之后得到操作數的有效地址。
BLNEXT
......
NEXT
......
MOV PC,LR
堆棧尋址:堆棧是一種數據結構,使用一個(gè)稱(chēng)作堆棧指針的專(zhuān)用寄存器指示當前的操作位置,堆棧指針總是指向棧頂。
遞增堆棧:向高地址方向生長(cháng)
遞減堆棧:向低地址方向生長(cháng)
滿(mǎn)堆棧:堆棧指針指向最后壓入堆棧的有效數據項
空堆棧:堆棧指針指向下一個(gè)要放入數據的空位置
ARM指令集
跳轉指令:實(shí)現程序流程的跳轉,1.使用專(zhuān)門(mén)的跳轉指令。2.直接向程序計數器PC寫(xiě)入跳轉地址值。(跳轉之前結合使用 MOV LR,PC.保存將來(lái)返回地址值,從而實(shí)現在4G連續的線(xiàn)性地址空間的子程序調用。)
指令:B、BL、BLX、BX
B{條件}
B Label
程序無(wú)條件跳轉到標號Label處執行
CMP
BEQ Label
當CPSR寄存器中的Z條件碼置位時(shí),程序跳轉到標號Label處執行。
BL{條件} 目標地址
在跳轉之前,會(huì )在寄存器R14中保存PC當前值。
BLX 目標地址
從ARM指令集跳轉到指令中所指定的目標地址,并將處理器的工作狀態(tài)由ARM狀態(tài)切換到Thumb狀態(tài),該指令同時(shí)將PC的當前內容保存到寄存器R14中。因此,當子程序使用Thumb指令集,而調用者使用ARM指令集時(shí),可以通過(guò)BLX指令實(shí)現子程序的調用和處理器工作狀態(tài)的切換。同時(shí),子程序的返回可以通過(guò)將寄存器R14值到PC中來(lái)完成。
BX{條件} 目標地址
目標地址可以是ARM指令,也可以是Thumb指令。
B
BL
BLX
BX
數據處理指令:數據傳送指令、算術(shù)邏輯運算指令和比較指令
MOV{條件}{S} 目的寄存器,源操作數
MOV指令完成從另一個(gè)寄存器、被移位的寄存器或進(jìn)一個(gè)立即數加載到目的寄存器。其中S選項決定指令的操作是否影響CPSR中條件標志位的值,當沒(méi)有S時(shí)指令不更新CPSR中條件標志位的值。
MOV R1, R0,LSL#3
MVN{條件}{S} 目的寄存器,源操作數
MVN指令可完成從另一個(gè)寄存器、被移位的寄存器、或將一個(gè)立即數加載到目的寄存器。與MOV指令不同之處是在傳送之前按位被取反了,即把一個(gè)被取反的值傳送到目的寄存器中。其中S決定指令的操作是否影響CPSR中條件標志位的值,當沒(méi)有S時(shí)指令不更新CPSR中條件標志位的值。
MVNR0,#0xff
CMP{條件}操作數1,操作數2
CMP指令用于把一個(gè)寄存器的內容和另一個(gè)寄存器的內容或立即數進(jìn)行比較,同時(shí)更新CPSR中條件標志位的值。該指令進(jìn)行一次減法運算,但不存儲結果,只更改條件標志位。標志位表示的是操作數1與操作數2的關(guān)系(大、小、相等),例如,當操作數1大于操作數2時(shí),此后的有GT后綴的指令將可以執行。
CMP R1,R0
CMPR1,#100
TST{條件} 操作數1,操作數2
TST指令用于把一個(gè)寄存器的內容和另一個(gè)寄存器的內容或立即數進(jìn)行按位的與運算,并根據運算結果更新CPSR中條件標志位的值。操作數1是要測試的數據,而操作數2是一個(gè)位掩碼(掩碼是一串二進(jìn)制代碼對目標字段進(jìn)行位與運算,屏蔽當前的輸入位),根據測試結果設置相應標志位。當位與結果為0時(shí),EQ位被設置。
TSTR1,#%1
ADD{條件}{S} 目的寄存器,操作數1,操作數2
ADD指令用于把兩個(gè)操作數相加,并將結果存放到目的寄存器中。操作數1應是一個(gè)寄存器,操作數2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數。
ADDR0,R1,R2,LSL#1
SUB{條件}{S} 目的寄存器,操作數1,操作數2
SUB指令用于把操作數1減去操作數2,并將結果存放到目的寄存器中。操作數1應是一個(gè)寄存器,操作數2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數。
SUBR0,R2,R3,LSL#1
AND{條件}{S} 目的寄存器,操作數1,操作數2
AND指令用于在兩個(gè)操作數上進(jìn)行邏輯與運算,并把結果放置到目的寄存器中。操作數1應是一個(gè)寄存器,操作數2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數。該指令常用于屏蔽操作數1的某些位。
ANDR0,R0,#3
ORR{條件}{S} 目的寄存器,操作數1,操作數2
ORR指令用于在兩個(gè)操作數上進(jìn)行邏輯或運算,并把結果放置到目的寄存器中。操作數1應是一個(gè)寄存器,操作數2應是一個(gè)寄存器,被移位寄存器,或一個(gè)立即數。該指令常用于設置操作數1的某些位。
ORRR0,R0,#3
BIC{cond}{S} Rd,Rn,operand2
BIC指令用于清除Rn中的某些位,并把結果存放在Rd中,操作數operand2為32位的掩碼,如果掩碼中設置了某一位為1,則清除這一位。
BICR0,R0,#11
MUL{條件}{S}
MUL指令完成將操作數1與操作數2的乘法運算并把結果放置到目的寄存器中,同時(shí)可以根據運算結果設置CPSR中相應的條件標志位。其中,操作數1和操作數2均為32位的有符號數或無(wú)符號數。
MUL
MULS
程序狀態(tài)寄存器訪(fǎng)問(wèn)指令
ARM微處理器支持程序狀態(tài)寄存器訪(fǎng)問(wèn)指令,用于在程序狀態(tài)寄存器和通用寄存器之間傳送數據。
MRS{條件} 通用寄存器,程序狀態(tài)寄存器(CPSR或SPSR)
MRS的用處是將狀態(tài)寄存器中的內容傳遞到通用寄存器中。
1、當需要修改程序狀態(tài)寄存器中內容時(shí),可用MRS進(jìn)程序狀態(tài)寄存器的內容讀入到通用寄存器,修改后再寫(xiě)回程序狀態(tài)寄存器。
2、當在異常處理或進(jìn)程切換時(shí),需要保存程序狀態(tài)寄存器的值,可先用MRS讀出程序狀態(tài)寄存器的值,然后保存。
MRS R0,CPSR
MSR{條件}程序狀態(tài)寄存器(CPSR或SPSR)_<域>,操作數
MSR指令用于將操作數的內容傳遞到程序狀態(tài)寄存器的特定域中。其中,操作時(shí)可以是通用寄存器或立即數。<域>用于設置程序狀態(tài)寄存器中需要操作的位,32位的程序狀態(tài)寄存器可分為4個(gè)域:
位[31:24]為條件標志位域,用f表示;
位[15:8]為擴展位域,用x表示;
MSR CPSR,R0
MSRCPSR_c,R0
評論