ARM 匯編指令條件執行
在ARM模式下,任何一條數據處理指令可以選擇是否根據操作的結果來更新CPSR寄存器中的ALU狀態標志位。在數據處理指令中使用S后綴來實現該功能。
不要在CMP,CMN,TST或者TEQ指令中使用S后綴。這些比較指令總是會更新標志位。
在Thumb模式下,所有數據處理指令都更新CPSR中的標志位。有一個例外就是:當一個或更多個高寄存器被用在MOV和ADD指令時,此時MOV和ADD不能更新狀態標志.
幾乎所有的ARM指令都可以根據CPSR中的ALU狀態標志位來條件執行。參見表2-1條件執行后綴表。
在ARM模式下,你可以:
根據數據操作的結果更新CPSR中的ALU狀態標志;
執行其他幾種操作,但不更新狀態標志;
根據當前狀態標志,決定是否執行接下來的指令。
在Thumb模式,大多數操作總是更新狀態標志位,并且只能使用條件轉移指令(B)來實現條件執行。該指令(B)的后綴和在ARM模式下是一樣的。其他指令不能使用條件執行。
ALU狀態標志
CPSR寄存器包含下面的ALU狀態標志:
N Set when the result of the operation was Negative
Z Set when the result of the operation was Zero
C Set when the operation result in a Carry(發生進位,或借位)
V Set when the operation caused oVerflow(操作造成溢出)
Q ARM architecture v5E only sticky flag
2.5.2 執行條件
N,Z,C,V相關的條件碼后綴如下表所列:
示例1
ADD r0, r1, r2 ; r0 = r1 + r2, 不更新標志位
ADDS r0, r1, r2 ; r0 = r1 + r2, 后綴S表示更新標志位
ADCSS r0, r1, r2 ; If C 標志為1,則執行r0 = r1 + r2, 且更新標志,
CMP r0, r1 ; CMP指令肯定會更新標志.
示例2 求最大公約數
gcd
CMP r0, r1
BEQ end ; r0 = r0 結束程序
BLT less ; r0 < r1 跳轉至 less
SUB r0, r0, r1 ; r0 > r1時 r0 = r0 - r1
B gcd ; 條件都不滿足是繼續循環
less
SUB r1, r1, r0 ; r0 < r1 r1 = r1 - r0
B gcd
end
示例3
MAIN
mov r1, #1
mov r2, #1
cmp r1, r2
beq FUNC ;if(eq) b FUNC => 實質:if(z == 1) b FUNC
bne FUNC ;實質:if(z == 0) b FUNC
mov r3, #3
mov r4, #4
FUNC
mov r5, #5
mov r6, #6
尋址方式
基地址變址尋址方式
種類 格式 模式
1 [Rn, #± 2 [Rn, ±Rm] 寄存器前索引尋址 3 [Rn, Rm, 4 [Rn, #± 5 [Rn, ±Rm]! 寄存器自動索引尋址 6 [Rn, Rm, 7 [Rn], #± 8 [Rn], ± 9 [Rn], ± 寄存器前索引尋址 mov r0, #0x40000000 mov r1, #0xF000000F str r1, [r0, #4] ;將 r1 中的數據存儲到地址為 r0 + 4 的內存空間中 寄存器移位的前索引尋址 mov r2, #8 str r1, [r0, r2, lsl #1] ;將 r1 中的數據存儲到地址為 r0 + (r2 << 1)的內存空間中 寄存器后索引尋址 str r1, [r0], #4 ;將 r1 中的數據存儲到地址為 r0 的內存空間中,然后 r0 = r0 + 4 寄存器自動索引尋址 str r1, [r0, #4]! ;將 r1 中的數據存儲到 r0 + 4 的內存空間中, 然后 r0 = r0 + 4 多寄存器尋址/塊拷貝尋址 LDM STM 對棧進行操作是,使用較多 比如說 用 IA 自動索引尋址存,就用 DB 自動索引讀 Load/Store指令 Load/store是一組內存訪問指令,用來在ARM寄存器和內存之間進行數據傳送,ARM指令中有3種基本的數據傳送指令。 單寄存器 Load/Store 內存訪問指令(single register):這些指令為ARM寄存器和存儲器提供了更靈活的單數據項傳送方式。數據可以使字節,16位半字或32位字 多寄存器 Load/Store 內存訪問指令:可以實現大量數據的同時傳送,主要用于進程的進入和退出、保存和恢復工作寄存器以及復制寄存器中的一片(一塊)數據 但寄存器交換指令(single register swap): 實現寄存器數據和內存數據進行交換,而且是在一條指令中完成,執行過程中不會受到中斷干擾 單寄存器Load/Store指令 LDR指令:用于從內存中將一個32位的字讀取到目標寄存器 指令格式 LDR{ ;指令舉例 LDR R1, [R0, #0x12] ;將R0 + 12地址處的數據讀出,保存到R1中(R0保持不變) LDR Rd,[Rn], #0x04 ;立即數后索引尋址,Rn的值用作傳輸數據的存儲地址。在數據傳送后,將偏移量 0x04 與Rn相加,記過寫回到 Rd中 STR指令:用于將一個32位的字節數據寫入到指令中指定的內存單元 指令格式 STR{ ;LOAD/STORE指令 ;向內存寫入數據 STR mov r0, #40000000 mov r1, #ff000000 str r1, [r0] ;用于將一個32位的字數據寫入到指令指定的內存單元(以 r0 值為起始地址的 4byte 內存單元) strb r1, [r0] ;將r1 中的 [7:0]存儲到 r0 對應的內存空間 strh r1, [r0] ;將r1 中的 [15:0]存儲到 r0 為起始地址的兩個字節的內存空間 ;在對數據進行操作時,應根據數據本身的屬性(幾個字節)進行操作 多寄存器Load/Store指令 LDM指令:實現數據從連續的內存單元中讀取到指令指定的寄存器列表中。值得注意的是 LDM指令和STM指令:序號的寄存器對應內存中高地址的數據 指令格式: LDM{ STM指令:實現將指令中寄存器列表里的數值寫入到一塊連續的內存單元之中 指令格式: STM{ LDM/STM 格 式 地址變化格式 1 IA(Increment After) 后遞增方式 先存儲后增長 2 IB(Increment Before) 先遞增方式 現增長后存儲 3 DA(Decrement After) 后遞減方式 先存儲后遞減 4 DB(Decrement Before) 先遞減方式 先遞減后存儲 mov r0, #0x40000000 mov r1, #1 mov r2, #2 mov r3, #3 ldm r0, {r1-r3} stm r0, {r1-r3} ;將 r1 - r3 寄存器(連續寄存器)中的數據存儲到 以 r0 位起始地址的內存空間中 stm r0, {r3, r1} ;將 r1 、 r3 寄存器(不連續寄存器)中的數據存儲到 以 r0 位起始地址的內存空間中 ;批量操作時,低編號的寄存器數據對應內存中的低地址 stm r0!, {r1-r3} ;寄存器批量存儲,也適用自動索引尋址, 操作完成后 r0 = r0 + (寄存器個數)*4 跳轉指令 B和BL跳轉指令 MAIN mov r0, #2 mov r1, #3 mov lr, pc ;B 指令不會自動保存 PC;手動保存返回地址、當前PC b lable ;跳轉到標號 FUNC (標號的實質是地址) mov r3, r0 FUNC sub r0, r1, r0 mov pc,lr ;返回主程序繼續執行 跳轉指令是改變指令執行順序的標準方式 (控制流指令) B 和 BL 指令都是 相對跳轉(短跳轉) 指令,通過偏移量跳轉, 最大跳轉距離是 ±32M 使用 mov pc, <>可以實現 對跳轉(長跳轉)(不會保存當前 PC 值) 關于B指令和BL指令最大跳轉距離是 ±32M: ARM匯編每條指令占用 4byte,生成機器碼 B 、BL存放在bits[31:24], bits[23:0]是立即數空間,可以表示 2^24個地址。由于每條匯編指令占用4byte字節(最低兩位都為 0),因此可以使用 24位二進制數來表示 26 位的尋址空間。 B指令和BL指令的區別: B指令在使用時不會對當前 PC 值進行保存,為保證跳轉指令執行后能正常返回,要手動對其進行保存 BL (帶連接的跳轉指令)能夠在跳轉時對當前 PC 值自動進行保存。 帶狀態切換的跳轉指令 BX 不會保存跳轉前 PC 值 ±32M范圍 帶狀態切換(ARM&Thmub)的跳轉指令BX ,語法格式:BX{ PC也可以作為 Rm 寄存器使用,當PC作為 Rm 使用時,指令 BX PC 便跳轉到當前指令下面第 2 條指令出執行(三級流水線:當前正在執行的指令地址為 PC - 8,正在譯碼的指令為 PC - 4, 正在取指的指令是 PC)。但這種方式不值得推薦,最好使用下面的方式完成這種跳轉。 mov pc, pc ;或者 add pc, pc, #0 帶狀態切換的連接跳轉指令 與BX功能一致,但會自動保存跳轉時的 PC 值,語法格式: BLX 狀態(寄存器)操作指令 ARM指令集提供了兩條指令(MSR,MRS),用來操作狀態寄存器PSR MRS指令,語法格式 MRS {cond} Rd, PSR 用于把CPSR或SPSR的值傳送到一個寄存器; MSR指令,語法格式 MSR {cond} PSR_filed, #immed_8r 或 MSR {cond} PSR_filed, Rm 用于把一個寄存器的值或一個立即數傳送到CPSR或SPSR;使用這兩條只能可以實現對程序狀態寄存器的狀態修改操作。 在使用MSR指令對PSR進行修改操作時,要通過field設置狀態寄存器需要操作的域。狀態寄存器的32位被分為4個8位的域(filed)分別為:bits[31:24]條件域,用 F 表示; bits[23: 16]狀態域,用 S 表示;bits[15:8]預留域,用 X 表示;bits[7:0]控制域,用 C 表示。 ;程序舉例:是能IRQ中斷 ENABLE_IRQ MRS R0,CPSR BIC R0,R0,#080 ;將CPSR bit7 I 清零,是能IRQ MSR CPSR_c,R0 ;典型的讀-改-回寫操作 MOV PC,LR 異常產生指令 ARM指令集提供了兩條產生異常的指令(中斷指令 SWI,斷點中斷指令 BKPT),通過這兩條指令可以用軟件的方法實現異常。 中斷指令 軟件中斷指令 SWI (software Interrupt)用于產生軟中斷,實現從用戶模式切換到管理模式,CPSR保存到管理模式的 SPSR 中,執行轉移到 SWI 向量。 語法格式 SWI { 棧 棧:按增長方向分為 遞增棧;遞減棧 按壓棧操作順序(sp位置)分為;滿棧和空棧 滿棧(FULL):sp指向棧頂元素 空棧(EMPTY):sp指向棧頂元素相鄰位置 根據棧的不同分類,將其尋址方式分為以下4種 1)滿遞減 FD(Full Descending) 2)空遞減 ED(Empty Descending) 3)滿遞增 FA(Full Asceding) 4)空遞增 EA(Empty Ascending) 習慣上大都使用滿減棧。 壓棧出棧的幾種操作方式 ;初始化棧 mov sp, #0x40000018 MAIN mov r0, #1 mov r1, #1 bl FUNC add r2, r0, r1 FUNC ;壓棧保護現場 stmfd sp!, {r0, r1} mov r0, #2 mov r1, #4 sub r2, r1, r0 ;出棧恢復現場 ldmfd sp!, {r0, r1} mov pc, lr ;初始化棧 MAIN mov r0, #1 mov r1, #1 bl FUNC add r2, r0, r1 FUNC ;壓棧保護現場 stmfd sp!, {r0, r1, lr} mov r0, #2 mov r1, #4 sub r2, r1, r0 ;出?;謴同F場 ldmfd sp!, {r0, r1, pc} swp r0, r1, [r2] ;將r0中的數據放入內存地址是r2的地址空間,同時將r2中的值放入r1寄存器 ;處理器與內存之間進行數據交換 交換過程不會被打斷
上一篇:4G通信模塊在ARM平臺下的應用
下一篇:ARM指令集——數據處理指令
推薦閱讀
史海拾趣
AOTC公司起源于一個由幾位電子工程專家組成的小團隊,他們共同研發出了一種新型的光電轉換器,具有更高的轉換效率和更小的體積。這一技術突破迅速吸引了風險投資家的注意,公司得到了初始的資金支持,并開始了正式的商業化進程。
隨著技術的不斷進步和市場需求的不斷變化,Fagor Electrónica開始將其業務范圍擴展到更廣泛的電子和數字領域。公司不斷推出新的產品和服務,以滿足不同客戶的需求。同時,Fagor Electrónica還積極拓展國際市場,將其產品銷往世界各地。這一時期的多元化發展和市場拓展為公司帶來了更大的商業機會和更廣闊的市場前景。
隨著技術的不斷進步和市場需求的不斷變化,Fagor Electrónica開始將其業務范圍擴展到更廣泛的電子和數字領域。公司不斷推出新的產品和服務,以滿足不同客戶的需求。同時,Fagor Electrónica還積極拓展國際市場,將其產品銷往世界各地。這一時期的多元化發展和市場拓展為公司帶來了更大的商業機會和更廣闊的市場前景。
進入XXXX年代,康龍公司意識到技術創新是企業持續發展的關鍵。于是,公司投入大量資金引進先進的生產設備和技術人才,加強研發力量。經過幾年的努力,康龍在精密模具設計和開發方面取得了重大突破,大大提高了生產效率和產品精度。同時,公司還注重產品質量的提升,通過嚴格的質量控制和檢驗流程,確保每一件產品都符合客戶的高標準要求。
在快速變化的市場環境中,創新成為DCD公司持續發展的關鍵。公司不斷加大研發投入,鼓勵員工提出創新性的想法和建議。同時,公司還積極引進國內外先進的技術和管理經驗,為公司的發展注入了新的活力。在創新驅動下,DCD公司不斷推出具有競爭力的新產品和解決方案,贏得了客戶的廣泛贊譽和市場的持續認可。
如何通過應用程序動態的設置改變串口過濾程序中要過濾的串口號的符號連接? 有這樣一段串口監視過濾驅動程序的代碼如下: RtlInitUnicodeString(&usDeviceToFilter, L\"\\\\??\\\\COM1\"); NtStatus = IoGetDeviceObjectPointer( ...… 查看全部問答∨ |
|
我把nboot燒寫到FLASH的BL0塊中,然后把EBOOT燒寫到BL2塊中,然后通過EBOOT把NK.BIN再下載到FLASH中, 問題一: 那么這個NK.BIN是被EBOOT下載到FLASH哪個地方的呢?是不是代碼在EBOOT哪個地方?還是在別的地方?能否告訴下小弟! 問題二: 為什么EBOOT非 ...… 查看全部問答∨ |
|
本人新手,對ZigBee基本不了解,現要做一個ZigBee的無線抄表系統中抄表終端到采集器間的軟件部分,請問各位我該怎么去做,用到的有CC2430,LED顯示模塊,幾個按鈕還有RS232串口。 最好有各個模塊的初始化代碼,以及各種功能的實現方法做參考。 謝 ...… 查看全部問答∨ |
#include \"DSP28_Device.h\" // DSP281x Headerfile Include File//#include \"DSP281x_Examples.h\" // DSP281x Examples Include File//#include \"f2812a.h\"#include\"math.h\" #define FIRNUMBER 25#de ...… 查看全部問答∨ |
最近在調幾個電源的輸出電流,開始電源的輸出電流是280ma,要把它調成260ma.這幾次都是都老大叫我調那個電阻我就調那個電阻,但是我不明白是為什么。有點是調IC的CS腳上的反饋電阻,有的是調FB引動上的電阻,有的是調次級反饋電路的電阻。這是為什 ...… 查看全部問答∨ |
代碼如下, 不知道是什么問題就是出不來,SPI用的430內部的SPI功能,求指導 #include \"msp430x14x.h\" //nRF24L01的數據寬度,地址寬度,以及數據定義 #define TX_ADR_WIDTH 5 #define RX_ADR_WIDTH 5 #define RX_PLOAD_WIDTH 5 #define TX ...… 查看全部問答∨ |