ARM指令集
計算機ARM操作指令系統
ARM指令集是指計算機ARM操作指令系統。在ARM中有兩種方式可以實現程序的跳轉:一種是跳轉指令;另一種是直接向PC寄存器(R15)中寫入目標地址值。
ARM指令集可以分為跳轉指令、數據處理指令、程序狀態寄存器(PSR)處理指令、載入/存儲指令、協處理器指令和異常產生指令六大類。
ADC | 帶進位的32位數加法 |
ADD | 32位數相加 |
AND | 32位數的邏輯與 |
B | 在32M空間內的相對跳轉指令 |
BEQ | 相等則跳轉(Branch if EQual) |
BNE | 不相等則跳轉(Branch if Not Equal) |
BGE | 大於或等於跳轉(Branch if Greater than or Equa) |
BGT | 大於跳轉(Branch if Greater Than) |
BIC | 32位數的邏輯位清零 |
BKPT | 斷點指令 |
BL | 帶鏈接的相對跳轉指令 |
BLE | 小於或等於跳轉(Branch if Less than or Equal) |
BLEQ | 帶鏈接等於跳轉(Branch with Link if EQual) |
BLLT | 帶鏈接小於跳轉(Branch with Link if Less Than) |
BLT | 小於跳轉(Branch if Less Than) |
BLX | 帶鏈接的切換跳轉 |
BX | 切換跳轉 |
CDP CDP2 | 協處理器數據處理操作 |
CLZ | 零計數 |
CMN | 比較兩個數的相反數 |
CMP | 32位數比較 |
EOR | 32位邏輯異或 |
LDC LDC2 | 從協處理器取一個或多個32位值 |
LDM | 從內存送多個32位字到ARM寄存器 |
LDR | 從虛擬地址取一個單個的32位值 |
MCR MCR2 MCRR | 從寄存器送數據到協處理器 |
MLA | 32位乘累加 |
MOV | 傳送一個32位數到寄存器 |
MRC MRC2 MRRC | 從協處理器傳送數據到寄存器 |
MRS | 把狀態寄存器的值送到通用寄存器 |
MSR | 把通用寄存器的值傳送到狀態寄存器 |
MUL | 32位乘 |
MVN | 把一個32位數的邏輯“非”送到寄存器 |
ORR | 32位邏輯或 |
PLD | 預裝載提示指令 |
QADD | 有符號32位飽和加 |
QDADD | 有符號雙32位飽和加 |
QSUB | 有符號32位飽和減 |
QDSUB | 有符號雙32位飽和減 |
RSB | 逆向32位減法 |
RSC | 帶進位的逆向32法減法 |
SBC | 帶進位的32位減法 |
SMLAxy | 有符號乘累加(16位*16位)+32位=32位 |
SMLAL | 64位有符號乘累加((32位*32位)+64位=64位) |
SMALxy | 64位有符號乘累加((32位*32位)+64位=64位) |
SMLAWy | 號乘累加((32位*16位)>>16位)+32位=32位 |
SMULL | 64位有符號乘累加(32位*32位)=64位 |
SMULxy | 有符號乘(16位*16位=32位) |
SMULWy | 有符號乘(32位*16位>>16位=32位) |
STC STC2 | 從協處理器中把一個或多個32位值存到內存 |
STM | 把多個32位的寄存器值存放到內存 |
STR | 把寄存器的值存到一個內存的虛地址內間 |
SUB | 32位減法 |
SWI | 軟中斷 |
SWP | 把一個字或者一個位元組和一個寄存器值交換 |
TEQ | 等值測試 |
TST | 位測試 |
UMLAL | 64位無符號乘累加((32位*32位)+64位=64位) |
UMULL | 64位無符號乘累加(32位*32位)=64位 |
算術和邏輯指令
ADC(AdditionwithCarry):帶進位的加法。
定義:ADC是將把兩個操作數加起來,並把結果放置到目的寄存器中。它使用一個進位標誌位,這樣就可以做比32位大的加法。
代碼:ADC{條件}{S},,
dest=op_1+op_2+carry
實例:
下列例子將加兩個128位的數。
128位結果:寄存器0、1、2、和3
第一個128位數:寄存器4、5、6、和7
第二個128位數:寄存器8、9、10、和11。
ADDSR0,R4,R8;加低端的字
ADCSR2,R6,R10;加第三個字,帶進位
ADCSR3,R7,R11;加高端的字,帶進位
注意:如果如果要做這樣的加法,不要忘記設置S後綴來更改進位標誌。
ADD(Addition):加法。
定義:ADD是將把兩個操作數加起來,把結果放置到目的寄存器中。
操作數1:是一個寄存器。
操作數2:可以是一個寄存器,被移位的寄存器,或一個立即值。
代碼:ADD{條件}{S},,
dest=op_1+op_2
實例:
ADDR0,R1,R2;R0=R1+R2
ADDR0,R1,#256;R0=R1+256
ADDR0,R2,R3,LSL#1;R0=R2+(R3<<1)
注意:加法可以在有符號和無符號數上進行。
AND(logicalAND):邏輯與。
定義:AND將在兩個操作數上進行邏輯與,把結果放置到目的寄存器中;對屏蔽你要在上面工作的位很有用。
操作數1:是一個寄存器。
操作數2:可以是一個寄存器,被移位的寄存器,或一個立即值。
代碼:AND{條件}{S},,
dest=op_1ANDop_2
實例:ANDR0,R0,#3;R0=保持R0的位0和1,丟棄其餘的位。
真值表(二者都是1則結果為1)
op_1 | op_2 | 結果 |
1 | ||
1 | ||
1 | 1 | 1 |
BIC(BitClear):位清除。
BIC是在一個字中清除位的一種方法,與OR位設置是相反的操作。操作數2是一個32位位掩碼(mask)。如果如果在掩碼中設置了某一位,則清除這一位。未設置的掩碼位指示此位保持不變。
BIC{條件}{S},,
dest=op_1AND(!op_2)
BICR0,R0,#%1011;清除R0中的位0、1、和3。保持其餘的不變
BIC真值表:
Op_1 | Op_2 | 結果 |
---|---|---|
1 | ||
1 | 1 | |
1 | 1 |
譯註:邏輯表達式為Op_1ANDNOTOp_2
EOR:邏輯異或
(logicalExclusiveOR)
EOR將在兩個操作數上進行邏輯異或,把結果放置到目的寄存器中;對反轉特定的位有用。操作數1是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即值
EOR{條件}{S},,
dest=op_1EORop_2
EORR0,R0,#3;反轉R0中的位0和1
EOR真值表(二者不同則結果為1):
Op_1 | Op_2 | 結果 |
---|---|---|
1 | 1 | |
1 | 1 | |
1 | 1 |
MOV:傳送
(Move)
MOV從另一個寄存器、被移位的寄存器、或一個立即值裝載一個值到目的寄存器。你可以指定相同的寄存器來實現NOP指令的效果,你還可以專門移位一個寄存器
MOV{條件}{S},
dest=op_1
MOVR0,R0;R0=R0...NOP指令
MOVR0,R0,LSL#3;R0=R0*8
如果R15是目的寄存器,將修改程序計數器或標誌。這用於返回到調用代碼,方法是把連接寄存器的內容傳送到R15:
MOVPC,R14;退出到調用者
MOVSPC,R14;退出到調用者並恢復標誌位
(不遵從32-bit體系)
MVN:傳送取反的值
(MoveNegative)
MVN從另一個寄存器、被移位的寄存器、或一個立即值裝載一個值到目的寄存器。不同之處是在傳送之前位被反轉了,所以把一個被取反的值傳送到一個寄存器中。這是邏輯非操作而不是算術操作,這個取反的值加1才是它的取負的值
MVN{條件}{S},
dest=!op_1
MVNR0,#4;R0=-5
MVNR0,#0;R0=-1
ORR:邏輯或
(logicalOR)
ORR指令用於在兩個操作數上進行邏輯或運算,並把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令常用於設置操作數1的某些位。
op2可以是寄存器、被移位的寄存器或立即數。一般用於設置Rn的特定幾位。
ORR{條件}{S},,
dest=op_1ORop_2
ORRR0,R0,#3;該指令設置R0的0、1位,其餘位保持不變。
ORRR0,R0,#5;R0的第0位和第2位設置為1,其餘位不變
OR真值表(二者中存在1則結果為1):
Op_1 | Op_2 | 結果 |
---|---|---|
1 | 1 | |
1 | 1 | |
1 | 1 | 1 |
RSB:反向減法
(ReverseSubtraction)
RSB用操作數two減去操作數one,把結果放置到目的寄存器中。操作數1是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即值
RSB{條件}{S},,
dest=op_2-op_1
RSBR0,R1,R2;R0=R2-R1
RSBR0,R1,#256;R0=256-R1
RSBR0,R2,R3,LSL#1;R0=(R3<<1)-R2
例如:
RSBR0,R1,#5;R0=5-R1
RSBR0,R1,R2;R0=R2-R1
RSBR0,R1,R2,LSL#5;R0=R2左移5位-R1
反向減法可以在有符號或無符號數上進行。
RSC:帶借位的反向減法
(ReverseSubtractionwithCarry)
RSC指令用於把操作數2減去操作數1,再減去CPSR中的C條件標誌位的反碼,並將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令使用進位標誌來表示借位,這樣就可以做大於32位的減法,注意不要忘記設置S後綴來更改進位標誌。該指令可用於有符號數或無符號數的減法運算。
RSC{條件}{S},,
dest=op_2-op_1-!carry
例如:
第一個64位操作數存放在寄存器R2,R3中;
第二個64位操作數存放在寄存器R4,R5中;
64位結果存放在R0,R1中。
64位的減法(第一個操作數減去第二個操作數)可由以下語句實現:
SUBSR0,R2,R4;低32位相減,S表示結果影響寄存器CPSR的值
RSCR1,R5,R3;高32位相減
SBC:帶借位的減法
(SubtractionwithCarry)
SBC做兩個操作數的減法,把結果放置到目的寄存器中。它使用進位標誌來表示借位,這樣就可以做大於32位的減法。SUB和SBC生成進位標誌的方式不同於常規,如果需要借位則清除進位標誌。所以,指令要對進位標誌進行一個非操作-在指令執行期間自動的反轉此位。op2可以是寄存器、被移位的寄存器或立即數。
SBC{條件}{S},,
dest=op_1-op_2-!carry
例如:
第一個64位操作數存放在寄存器R2,R3中;
第二個64位操作數存放在寄存器R4,R5中;
64位結果存放在R0,R1中。
64位的減法(第一個操作數減去第二個操作數)可由以下語句實現:
SUBSR0,R2,R4;低32位相減,S表示結果影響條件標誌位的值
SBCR1,R3,R5;高32位相減
SUB:減法
(Subtraction)
SUB用操作數one減去操作數two,把結果放置到目的寄存器中。操作數1是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即值
SUB{條件}{S},,
dest=op_1-op_2
例如:
SUBR0,R1,#5;R0=R1-5
SUBR0,R1,R2;R0=R1-R2
SUBR0,R1,R2,LSL#5;R0=R1-R2左移5位
SUBR0,R1,R2;R0=R1-R2
SUBR0,R1,#256;R0=R1-256
SUBR0,R2,R3,LSL#1;R0=R2-(R3<<1)
減法可以在有符號和無符號數上進行。
移位指令
ARM處理器組建了可以與數據處理指令(ADC、ADD、AND、BIC、CMN、CMP、EOR、MOV、MVN、ORR、RSB、SBC、SUB、TEQ、TST)一起使用的桶式移位器(barrelshifter)。你還可以使用桶式移位器影響在LDR/STR操作中的變址值。
譯註:移位操作在ARM指令集中不作為單獨的指令使用,它是指令格式中是一個欄位,在彙編語言中表示為指令中的選項。如果數據處理指令的第二個操作數或者單一數據傳送指令中的變址是寄存器,則可以對它進行各種移位操作。如果數據處理指令的第二個操作數是立即值,在指令中用8位立即值和4位循環移位來表示它,所以對大於255的立即值,彙編器嘗試通過在指令中設置循環移位數量來表示它,如果不能表示則生成一個錯誤。在邏輯類指令中,邏輯運算指令由指令中S位的設置或清除來確定是否影響進位標誌,而比較指令的S位總是設置的。在單一數據傳送指令中指定移位的數量只能用立即值而不能用寄存器。
下面是給不同的移位類型的六個助記符:
LSL邏輯左移
ASL算術左移
LSR邏輯右移
ASR算術右移
ROR循環右移
RRX帶擴展的循環右移
ASL和LSL是等同的,可以自由互換。
你可以用一個立即值(從0到31)指定移位數量,或用包含在0和31之間的一個值的寄存器指定移位數量。
LSL/ASL:邏輯或算術左移
(LogicalorArithmeticShiftLeft)
接受Rx的內容並按用‘n’或在寄存器Rn中指定的數量向高有效位方向移位。最低有效位用零來填充。除了概念上的第33位(就是被移出的最小的那位)之外丟棄移出最左端的高位,如果邏輯類指令中S位被設置了,則此位將成為從桶式移位器退出時進位標誌的值。
LSL(或ASL)可完成對通用寄存器中的內容進行邏輯(或算術)的左移操作,按操作數所指定的數量向左移位,低位用零來填充。其中,操作數可以是通用寄存器,也可以是立即數(0~31)。
Rx,LSL#nor
Rx,ASL#nor
Rx,LSLRnor
Rx,ASLRn
考慮下列:
MOVR1,#12
MOVR0,R1,LSL#2
在退出時,R0是48。這些指令形成的總和是R0=#12,LSL#2等同於BASIC的R0=12<<2
MOVR0,R1,LSL#2;將R1中的內容左移兩位後傳送到R0中。
LSR:邏輯右移
(LogicalShiftRight)
它在概念上與左移相對。把所有位向更低有效位方向移動。如果邏輯類指令中S位被設置了,則把最後被移出最右端的那位放置到進位標誌中。它同於BASIC的register=value>>>shift。
LSR可完成對通用寄存器中的內容進行右移的操作,按操作數所指定的數量向右移位,左端用零來填充。其中,操作數可以是通用寄存器,也可以是立即數(0~31)。
Rx,LSR#nor
Rx,LSRRn
操作示例:
MOVR0,R1,LSR#2;將R1中的內容右移兩位後傳送到R0中,左端用零來填充。