一、匯編基本概要
1、ARM數據和指令類型
2、ARM字節順序
????????即可大端存儲也可小端存儲,默認小端存儲(不建議修改)、
? ? ? ? kernel(內核)中的,CPSR(當前程序狀態寄存器)可修改大小端存儲
3、ARM處理器工作模式
? ? ? ? 前七個重要
4、寄存器組織
5、程序狀態寄存器(CPSR)
? ? ? ? 此圖可做概念理解,部分實際參數有問題
6、異常處理
(1)概念
????????異常向量表是ARM處理器中用于處理異常和中斷的核心機制,包含各類異常處理程序的入口地址或跳轉指令。當異常發生時,處理器會自動跳轉到對應向量地址執行處理程序
(2)關鍵功能
????????快速響應異常,保存現場(LR、SPSR),切換處理器模式。
????????提供標準化異常入口,確保系統穩定性和實時性
(2)異常向量表? ??
異常類型 | 向量地址 |
---|---|
復位(Reset) | 0x00000000 |
未定義指令(Undefined Instruction) | 0x00000004 |
軟件中斷(SWI) | 0x00000008 |
預取指令異常(Prefetch Abort) | 0x0000000C |
數據異常(Data Abort) | 0x00000010 |
保留(Reserved) | 0x00000014 |
外部中斷(IRQ) | 0x00000018 |
快速外部中斷(FIQ) | 0x0000001C |
二、實現匯編操作
1、格式
????偽操作:它們不是 ARM 處理器實際的指令(如 MOV, ADD 等),而是寫給匯編器看的命令,用于指導匯編器如何工作
area reset, code, readonly
code32
entry
end?? ?
area: 這是最重要的一個偽操作,用于定義一個段。程序、數據、堆棧等都需要被組織在不同的段中
reset: 這是你為這個段起的名字。名字 reset 具有很強的暗示性,通常用于表示復位向量段,即CPU上電或復位后首先執行的第一段代碼所在的位置
code: 指定該段的屬性為代碼,意味著這個段包含可執行的指令
readonly: 指定該段的屬性為只讀。對于代碼段來說,這通常是默認且必須的
?? ?code32: 表示后續指令使用 32位的 ARM 指令集
thumb: 表示后續指令使用 16位的 Thumb 指令集
2、指令?? ?
? ? (1)mov
?? ??? ?MOV{S}<c> <Rd>, #<const>
MOV{S}<c> <Rd>, <Rm>?? ??? ?MOV instruction ? ??? ??? ??? ?Canonical form
MOV{S} <Rd>, <Rm>, ASR #<n> ASR{S} <Rd>, <Rm>, #<n>
MOV{S} <Rd>, <Rm>, LSL #<n> LSL{S} <Rd>, <Rm>, #<n>
MOV{S} <Rd>, <Rm>, LSR #<n> LSR{S} <Rd>, <Rm>, #<n>
MOV{S} <Rd>, <Rm>, ROR #<n> ROR{S} <Rd>, <Rm>, #<n>
MOV{S} <Rd>, <Rm>, ASR <Rs> ASR{S} <Rd>, <Rm>, <Rs>
MOV{S} <Rd>, <Rm>, LSL <Rs> LSL{S} <Rd>, <Rm>, <Rs>
MOV{S} <Rd>, <Rm>, LSR <Rs> LSR{S} <Rd>, <Rm>, <Rs>
MOV{S} <Rd>, <Rm>, ROR <Rs> ROR{S} <Rd>, <Rm>, <Rs>
MOV{S} <Rd>, <Rm>, RRX ?? ??? ?RRX{S} <Rd>, <Rm>
- 注意?? ?
- (1)與C語言中的賦值運算對比(左值/右值),利于加深理解
- (2)#<n>/<Rs> 取值范圍 (0 - 31)
- (3)RRX{S}:擴展右移 (不需要移位量)
- (4)在計算機中只識別二進制數據,計算機沒有有無符號,浮動點等概念;
? (2)add(加法指令)
????????
????????立即數作為第二操作數:? ? ? ? ? ? ? ?ADD{S}<c> <Rd>, <Rn>, #<const>
寄存器作為第二操作數寄存器:?? ?ADD{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
寄存器作為第二操作數移位量:?? ?ADD{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
- 注意??
- ?{, <shift>} 其中{}代表可選擇,“,”表示在使用時需要在Rm后添加“,” shift 移位量(立即數)
- ?add r0, #3, #2 :為什么沒有這種形式,C語言int a = 1 + 2; 編譯階段計算, 不需要在機器指令中體現??
? ? (3)sub(減法指令)
立即數作為第二操作數:?? ??? ?SUB{S}<c> <Rd>, <Rn>, #<const>
寄存器作為第二操作數寄存器:?? ?SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
寄存器作為第二操作數移位量:?? ?SUB{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
(4)立即數(imm)? ? ??
?????????以上指令都有立即數作為第二操作數的情況,準確的說這里所指的是12位立即數imm12
????????12位立即數的條件是:?
????????判斷標準:把某個數展開成2進制,該數必須存在一種循環右移(偶數位),使得移位后高24位全0,低8位即為有效imm8;
(5)ldr(加載指令)
LDR<c> <Rt>, <label>
?(6)sdr(存放指令)
? ?(7)MVN(按位取反移動指令)
MVN{S}<c> <Rd>, #<const>
MVN{S}<c> <Rd>, <Rm>{, <shift>}
MVN{S}<c> <Rd>, <Rm>, <type> <Rs>
?? ?(8)bic(bit clear):指定位置清0
BIC{S}<c> <Rd>, <Rn>, #<const>
BIC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
BIC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>??? ??? ?
? ? (9)orr(or):指定位置1
ORR{S}<c> <Rd>, <Rn>, #<const>
ORR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
ORR{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
(10)條件判斷標志NZCV
????????CPSR寄存器中條件判斷標志位
N: 符號標志位:上條指令執行結果最高位bit31為1,則 N = 1, 當結果作為有符號解釋時為負值;
Z: 零值標志位:上條指令執行結果為0(即bit0 - bit31 均為0),則 Z = 1;
C: 進位標志位:進行無符號解讀,如果在加法過程中進位或者減法時沒有借位,則為 C = 1,否則 C = 0
V: 溢出標志位:進行有符號解讀,是否發生溢出 -2^31 - 2^31-1(兩個正數加得負數,兩個負數加得正數)
條件碼:eq ge gt le lt al(無條件執行)
equal:等于
not equal:不等于
? ? (11)cmp(compare):比較指令
CMP<c> <Rn>, #<const>
CMP<c> <Rn>, <Rm>{, <shift>}
CMP<c> <Rn>, <Rm>, <type> <Rs>
cmp r0, r1 <==> subs r0, r1
比較兩個數中的最大值
? (12)b bl bx :(跳轉指令)
? ? ? ? 類似于c語言goto
B<c> <label>
b fun <==> ldr pc, =fun
BL<c> <label>
bl fun
BX<c> <Rm>
bx lr <==> mov pc, lr