ARM指令集可以分爲數據處理指令、跳轉指令、Load/Store指令、程序狀態寄存器傳輸指令、協處理器指令和異常中斷產生指令。根據使用的指令類型不同,指令的尋址方式分爲數據處理指令尋址方式和內存訪問指令尋址方式。
數據處理指令尋址方式
概述:數據操作指令是指對存放在寄存器中的數據進行操作的指令。主要包括數據傳送指令、算術指令、邏輯指令、比較與測試指令及乘法指令。如果在數據處理指令後使用“S”後綴,指令的執行結果將會影響CPSR中的標誌位。數據處理指令的基本語法格式如下:
1.MOV指令
MOV是最簡單的ARM指令,MOV指令是將《shifter_operand》表示的數據傳送到目標寄存器《Rd》中,其中《shifter_operand》可以是寄存器,也可以使立即數,並根據操作的結果更新CPSR中相應的條件標誌位。
語法格式:
MOV { <cond> } { S } <Rd>,<shifter_operand>
指令舉例:
MOV R0,#0xFF ; //R0=0xFF
MOV R0,RO ; //R0=R0.....NOP指令
MOV RO,RO,LSL#3; //RO=RO<<3
當R15作爲目標寄存器Rd出現時常用於子函數的返回,方法是將連接寄存器LR中保存的返回地址通過該指令傳送給PC。
MOV PC,R14; //退出到調用者,用於普通函數返回,PC即R15
MOVS PC,R14; //退出到調用者並恢復標誌位,用於異常函數返回
指令功能:
- 將數據從一個寄存器傳送到另一個寄存器。
- 將一個常數值傳送到另一個寄存器。
- 實現單純的移位操作,比如操作數除以2^n可以用右移n位來實現。
- 當PC(R15)用作目標寄存器Rd時,可以實現程序跳轉,如“MOV PC,LR”。這種跳轉可以實現子程序條用及從子程序返回。
- 當PC作爲目標寄存器Rd且指令中有後綴“S”時,則指令在執行跳轉操作的同時,將當前處理器模式的SPSR寄存器的內容複製到CPSR中。這種指令“MOVS PC,LR”,可以實現從某些異常中斷中返回。
2.MVN指令
MVN是數據取反傳送指令,指令將《shifter_operand》表示的數據的反碼傳送到目標寄存器《Rd》,並根據操作的結果更新CPSR中相應的條件標誌位。
語法格式:
MVN { <cond> } { S } <Rd>,<shifter_operand>
指令舉例:
MVN指令和MOV指令相同,《shifter_operand》可以是立即數,也可以是寄存器。
MVN R0,#4; //R0=~(4)
MVN R0,#0; //RO=~(1)
指令功能:
- 想寄存器中傳送一個負數。
- 生成位掩碼。
- 求一個數的反碼。
3.ADD指令
ADD指令將《shifter_operand》表示的數據加上寄存器《Rn》的值,將結果保存到目標寄存器《Rd》中,並根據指令的執行結果更新CPSR中相應的條件標誌位。
語法格式:
ADD { <cond> } { S } <Rd>,<Rn>, <shifter_operand>
指令舉例:
ADD R0,R1,R2; //R0=R1+R2
ADD R0,R1,#0xFF; //R0=R1+0xFF
ADD R0,R2,R3,LSL#1; //R0=R2+(R3<<1)
指令功能:
- 主要完成兩個數的相加。
4.ADC指令
ADC指令將《shifter_operand》表示的值加上寄存器《Rn》的值,再加上CPSR中的C條件標誌位的值,將結果保存到目標寄存器《Rd》中,並根據指令的執行結果更新CPSR中相應的條件標誌位。
語法格式:
ADC { <cond> } { S } <Rd>,<Rn>, <shifter_operand>
指令舉例:
ADC指令把兩個操作數加起來,並把結果放置到目標寄存器《Rd》中。它使用CPSR中的進位標誌位,這樣就可以做比32位大的加法。
下面的例子將兩個128位的數相加。
128位結果:寄存器R0、R1、R2和R3.
第1個128位數:寄存器R4、R5、R6和R7
第2個128位數:寄存器R8、R9、R10和R11
ADDS R0,R4,R8; //加低端的字
ADCS R1,R5,R9; //加下一個字,帶進位
ADCS R2,R6,R10; //加第3個字,帶進位
ADCS R3,R7,R11; //加高端的字,帶進位
指令功能:
ADC指令常與ADD指令聯合使用,可以實現兩個64位數的相加。
5.SUB 指令
SUB指令的作用是將寄存器《Rn》中的數值減去《shifter_operand》所表示的數值,將運算結果保存到目標寄存器《Rd》中,並根據指令的執行結果更新CPSR中的條件標誌位。
語法格式:
SUB { <cond> } { S } <Rd>,<Rn>, <shifter_operand>
指令舉例:
SUB R0,R1,R2; //R0=R1-R2
SUB R0,R1,#0xff; //R=R1-0xff
SUB R0,R2,R3,LSL#1; //R0=R2-(R3<<1)
指令功能:
SUB指令常用於實現兩個數的減法。
6.AND指令
AND指令將《shifter_operand》表示的數值與寄存器《Rn》的值按位做“與”操作,並將結果保存到目標寄存器《Rd》中,同時根據操作的結果更新CPSR寄存器中的條件標誌位。
語法格式:
ADD { <cond> } { S } <Rd>,<Rn>, <shifter_operand>
指令舉例
AND R0,R0,#0x03; //r0寄存器的0、1位不變,其他位清零
AND R2,R1,R3; //R2=R1 & R3
AND R0,R0,#0x01; //R0=R0 & 0X01
7.EOR指令
EOR指令將寄存器《Rn》中的值和《shifter_operand》表示的值進行按位“異或”操作,並將執行結果存儲到目標寄存器《Rd》中,同時根據指令的執行結果更新CPSR中相應的條件標誌位。
語法格式:
EOR { <cond> } { S } <Rd>,<Rn>, <shifter_operand>
指令舉例:
EOR R0,R0,#3; //反轉R0中的第0和1位
EOR R1,R1R,#0x0F; //將R1的低4位取反
EOR R2,R1,R0; //R2=R1^R0
EORS R0,R5,#0X01; //將R5和0x01進行邏輯異或,結果保存到R0,並根據執行結果更新標誌位。
8.BIC指令
BIC位清零指令,將寄存器《Rn》的值與第2個源操作數《shifter_operand》的值的反碼按位做“邏輯與”操作,結果保存到寄存器《Rd》中。
語法格式:
BIC { <cond> } { S } <Rd>,<Rn>, <shifter_operand>
指令舉例:
BIC R0,R0,#0X1011; //清除R0中的位0、1和3,保持其餘不變
BIC R1,R2,R3; //將R3的反碼和R2邏輯與,結果保存到R1中
9.CMP指令
CMP指令的實質是使用寄存器《Rn》的值減去《shifter_operand》表示的值,根據操作的結果更新 CPSR 中相應的條件標誌位,以便後面的指令根據相應的條件標誌來判斷是否執行。
語法格式:
CMP { <cond> } { S } <Rd>,<Rn>, <shifter_operand>
指令舉例:
CMP指令允許把一個寄存器的內容與另一個寄存器的內容或立即數進行比較,比較結果將更改狀態寄存器中對應的標誌從而之後的指令可以進行條件執行。它的實質是進行了一次減法,但不存儲結果,而是更改條件標誌位。標誌位表示的是操作數1與操作數2比較的結果(其值可能爲大、小、相等)。比如操作數1大於操作數2,則此後的有GT後綴的指令將可以執行。
顯然,CMP不需要顯式地指定S後綴來更改狀態標誌。
CMP R1.#10 ; //比較R1和立即數10並更新相關的標誌位
CMP R1.R2 ; //比較寄存器R1和R2中的值並設置相關的標誌位
通過上面的例子可以看出,CMP 指令與SUBS 指令的區別在於 CMP指令不保存運算結果,在進行兩個數據大小判斷時,常用CMP指令及相應的條件碼來進行操作.