ARM體系結(jié)構(gòu)的數(shù)據(jù)存儲格式
- 小端:低位放在低地址
- 大端:低位放在高地址
指令長度及數(shù)據(jù)類型
1.CPU與內(nèi)存之間的連線:中間是用數(shù)據(jù)總線(32根線就能表示CPU是32位即4個字節(jié))連接的
2.字節(jié):8位
3.半字:16位
4.字:32位
異常
- 只要正常的程序流被暫時中止,處理器進入異常模式。例如響應(yīng)一個來自外設(shè)的中斷。在處理異常之前,ARM9內(nèi)核保存當前的處理器狀態(tài)(CPSR>SPSR),這樣當處理程序結(jié)束時可以恢復(fù)執(zhí)行原來的程序()(SPSR->CPSR)
- 如果同時發(fā)生兩個或更多的異常,那么將按照固定的順序來處理異常,即異常優(yōu)先級
異常優(yōu)先級

Paste_Image.png

Paste_Image.png
復(fù)位異常

Paste_Image.png
未定義指令異常

Paste_Image.png
軟件中斷異常

Paste_Image.png
預(yù)取中止異常

Paste_Image.png
IRQ

Paste_Image.png
FIQ

Paste_Image.png
數(shù)據(jù)中止異常

Paste_Image.png
對異常的響應(yīng)
- 在異常發(fā)生后,ARM9內(nèi)核會作以下工作
- 在適當?shù)腖R中保存下一條指令的地址,當異常入口來自:
1.ARM狀態(tài),那么ARM9將當前指令地址加4或8復(fù)制(取決于異常的類型)到LR中
2.為Thumb狀態(tài),那么ARM9將當前指令地址加2,4或加8(取決于異常的類型)復(fù)制到LR中,異常處理器程序不必確定狀態(tài)
3.如果同時發(fā)生兩個或更多異常,那么將按照異常的優(yōu)先級的順序來處理異常
- 將CPRS復(fù)制到適當?shù)腟PSR中
- 將CPSR模式位強制設(shè)置為與異常類型相對應(yīng)的值
- 強制PC從相關(guān)的異常向量處取指
- ARM9內(nèi)核在處理中斷異常時置位中斷禁止標志,這樣可以防止不受控制的異常嵌套
ARM微處理器指令系統(tǒng)
ARM微處理器的指令的分類與格式
ARM是三地址指令格式,指令的基本格式如下
1.<opcode> {<cond>} {s} <Rd>,<Rn>{,<operand2>}
- 其中<>號內(nèi)的項時必須的,{}號內(nèi)的項時可選的.
opcode:指令助記符;
cond:執(zhí)行條件;
s:是否影響CPSR寄存器的值;
Rd:目標寄存器
Rn:第1個操作數(shù)的寄存器
operand2:第2個操作數(shù)
指令的條件域
<opcode> {<cond>} {S} <Rd>,<Rn>{,<operand2>}
- 使用條件碼"cond"可以實現(xiàn)高效的邏輯操作(節(jié)省跳轉(zhuǎn)和條件語句),提高代碼效率
- 所有的ARM指令都可以條件執(zhí)行,而Thumb指令只有B(跳轉(zhuǎn))指令具有條件執(zhí)行功能.如果指令不標明條件代碼,將默認為無條件(AL)執(zhí)行
指令的條件域
- 指令條件碼表

Paste_Image.png
- 示例
(1)C代碼
if(a>b)
{
a++;
}
else
{
b++;
}
(2)對應(yīng)的匯編代碼
CMP R0,R1//R0(a)與R1(b)比較
ADDHI R0,R0,#1//若R0>R1,則R0=R0+1
ADDLS R1,R1,#1//若R0<=R1,則R1=R1+1
### ARM指令集
#### 跳轉(zhuǎn)指令
>- 在ARM中有兩種方式可以實現(xiàn)程序的跳轉(zhuǎn),一種是使用分支指令直接跳轉(zhuǎn),另一種則是直接向PC寄存器賦值實現(xiàn)跳轉(zhuǎn)(MOV指令).分支指令有一下三種:
>1.分支指令B
>2.帶鏈接的分支指令BL
>3.帶狀態(tài)切換的分支指令BX
>4.帶返回和狀態(tài)切換的跳轉(zhuǎn)指令BLX
ADRL R0,ThumbFun+1 //將Thumb程序的入口加1存入R0 (+1表示狀態(tài)切換)
BX R0
#### 數(shù)據(jù)處理指令
>- 數(shù)據(jù)處理指令大致可分為3類
>1.數(shù)據(jù)傳送指令
>2.算術(shù)邏輯運算運算
>3.比較指令
>- 數(shù)據(jù)處理指令只能對寄存器的內(nèi)容進行操作,而不能對內(nèi)存中的數(shù)據(jù)進行操作.所有ARM數(shù)據(jù)處理指令均可選擇使用S后綴,以使指令影響狀態(tài)標志
### 乘法指令
#### 乘法與乘加指令


>- MUL Rd,Rm,Rs//Rm*Rs放入Rd
>- 64位無符號乘法指令:UMULL RdLo,RdHi,Rm,Rs //Rm*Rs的低32位放在RdLo里,高32位放在RdHi里面
### 程序狀態(tài)寄存器訪問指令
>- MRS{cond} Rd,psr
>- MRS:將psr寄存器里面的值存放到CPU里面的寄存器
>- MSR:將CPU里面的寄存器的內(nèi)容存放到指定的psr寄存器中
### ARM指令的尋址方式
#### 立即數(shù)尋址
>- mov r0 #10
>- 判斷立即數(shù)是否合法:將立即數(shù)(16進制)用二進制表示,再將低位與高位的偶數(shù)個0去掉,剩下的位數(shù)<=8位,則合法,否則不合法
#### 立即數(shù)續(xù)

#### 寄存器尋址
>- mov R1,R2//將R2的值放入R1中
>- SUB R,R1,R2//
#### 寄存器間接尋址
>- LDR R1,[R2] //將R2指向的存儲單元的數(shù)據(jù)讀出保存到R1寄存器中
>- SWP R1,R1,[R2]
>- 可以訪問內(nèi)存空間的指令:LDxxx,STxxx,SWPxxx
#### 寄存器偏移尋址
>- mov R0,R2,LSL #3//將R2里面的值邏輯左移3位再放到R0中
>- mov R0,R2,LSL R1
>1.邏輯左移:LSL 高位扔掉,低位補0
>2.邏輯右移:LSR 低位扔掉,高位補0
>3.數(shù)學(xué)左移:ASL 拿符號位,補低位
>4.數(shù)學(xué)右移:ASR 拿到高位,補0
>5.循環(huán)右移:ROR 低位拿出,補高位
>6.帶擴展的循環(huán)右移:RRX
>7.桶形移位器
#### 基址變址尋址
>- (前索引)LDR R2,[R3,#0x0C]//讀取R3+0x0C地址上的存儲單元的內(nèi)容,放入R2
>- STR R1,[R0,#-4]!//先R0=R0-4,然后把R0的值寄存到保存到R1指定的存儲單元
>- (后索引)LDR R0,[R1],#4//將R1指向的存儲單元的值放到R0,然后R1的地址加4


#### 多寄存器尋址
>- LDMIA R1!,{R2-R4,R12}//將R1指向的單元中的數(shù)據(jù)讀出到R2-R4 、R12中(R1自動加4)
>- STMIA R0!{R2-R4,R12}//將R2-R4 、R12指向的單元中的值保存到R0指向的數(shù)據(jù)單元中(R0自動加4)
##### 多寄存器尋址續(xù)(基址寄存器的增長方式)
>1.IA:每次傳送后地址增加4
>2.IB:每次傳送前地址增加4
### 堆棧尋址
>- 堆棧是一個按特定順序存取的存儲區(qū),操作順序為"后進先出".堆棧尋址是隱含的,它使用一個專門的寄存器(堆棧指針)指向一塊存儲區(qū)域(堆棧),指針所指向的存儲單元即是堆棧的棧頂.存儲器堆棧可分為兩種:
>1.向上生長:向高地址方向生長,稱為遞增堆棧
>2.向下生長:向低地址方向生長,稱為遞減堆棧

>- 堆棧指針指向最后壓入的堆棧的有效數(shù)據(jù)項,稱為滿堆棧;堆棧指針指向下一個待壓入數(shù)據(jù)額空位置,稱為空堆棧

##### 堆棧尋址續(xù)

#### 相對尋址
BL SUBR1//調(diào)用到SUBR1子程序
BEQ LOOP//條件跳轉(zhuǎn)到LOOP標號處
......
LOOP MOV R6,#1
......
SUBR1
### ARM匯編語言的基本框架
AREA ARMexp1,CODE,READONLY
ENTRY
start
MOV r0,#10
MOV r1,#3
ADD r0,r0,r1
stop
MOV r0,#0x18
LDR r1,=0x20026
SWI 0x123456
END
### C語言編譯的幾個步驟
>1.預(yù)處理:傻替換,條件編譯
>2.編譯:把C語言程序翻譯成匯編語言的程序編
>3.匯編:把每一條指令翻譯成二進制語句
>4.鏈接
預(yù)處理 編譯 匯編 鏈接
1.c 1.i 1.S 1.o 將1.o,2.o,3.o,庫文件 生成可執(zhí)行的文件
2.c 2 .i 2.S 2.o
3.c 3.i 3.S 3.o
>- register int i;//如果有寄存器可用,則將i變量保存到寄存器中,不放在內(nèi)存中,
>- register int &i//是錯誤的,因為不在內(nèi)存里,所以沒有地址(以防可能有寄存器或無寄存器,都不要這樣寫)