ARM體系結構的數據存儲格式
- 小端:低位放在低地址
- 大端:低位放在高地址
指令長度及數據類型
1.CPU與內存之間的連線:中間是用數據總線(32根線就能表示CPU是32位即4個字節)連接的
2.字節:8位
3.半字:16位
4.字:32位
異常
- 只要正常的程序流被暫時中止,處理器進入異常模式。例如響應一個來自外設的中斷。在處理異常之前,ARM9內核保存當前的處理器狀態(CPSR>SPSR),這樣當處理程序結束時可以恢復執行原來的程序()(SPSR->CPSR)
- 如果同時發生兩個或更多的異常,那么將按照固定的順序來處理異常,即異常優先級
異常優先級
Paste_Image.png
Paste_Image.png
復位異常
Paste_Image.png
未定義指令異常
Paste_Image.png
軟件中斷異常
Paste_Image.png
預取中止異常
Paste_Image.png
IRQ
Paste_Image.png
FIQ
Paste_Image.png
數據中止異常
Paste_Image.png
對異常的響應
- 在異常發生后,ARM9內核會作以下工作
- 在適當的LR中保存下一條指令的地址,當異常入口來自:
1.ARM狀態,那么ARM9將當前指令地址加4或8復制(取決于異常的類型)到LR中
2.為Thumb狀態,那么ARM9將當前指令地址加2,4或加8(取決于異常的類型)復制到LR中,異常處理器程序不必確定狀態
3.如果同時發生兩個或更多異常,那么將按照異常的優先級的順序來處理異常
- 將CPRS復制到適當的SPSR中
- 將CPSR模式位強制設置為與異常類型相對應的值
- 強制PC從相關的異常向量處取指
- ARM9內核在處理中斷異常時置位中斷禁止標志,這樣可以防止不受控制的異常嵌套
ARM微處理器指令系統
ARM微處理器的指令的分類與格式
ARM是三地址指令格式,指令的基本格式如下
1.<opcode> {<cond>} {s} <Rd>,<Rn>{,<operand2>}
- 其中<>號內的項時必須的,{}號內的項時可選的.
opcode:指令助記符;
cond:執行條件;
s:是否影響CPSR寄存器的值;
Rd:目標寄存器
Rn:第1個操作數的寄存器
operand2:第2個操作數
指令的條件域
<opcode> {<cond>} {S} <Rd>,<Rn>{,<operand2>}
- 使用條件碼"cond"可以實現高效的邏輯操作(節省跳轉和條件語句),提高代碼效率
- 所有的ARM指令都可以條件執行,而Thumb指令只有B(跳轉)指令具有條件執行功能.如果指令不標明條件代碼,將默認為無條件(AL)執行
指令的條件域
- 指令條件碼表
Paste_Image.png
- 示例
(1)C代碼
if(a>b)
{
a++;
}
else
{
b++;
}
(2)對應的匯編代碼
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指令集
#### 跳轉指令
>- 在ARM中有兩種方式可以實現程序的跳轉,一種是使用分支指令直接跳轉,另一種則是直接向PC寄存器賦值實現跳轉(MOV指令).分支指令有一下三種:
>1.分支指令B
>2.帶鏈接的分支指令BL
>3.帶狀態切換的分支指令BX
>4.帶返回和狀態切換的跳轉指令BLX
ADRL R0,ThumbFun+1 //將Thumb程序的入口加1存入R0 (+1表示狀態切換)
BX R0
#### 數據處理指令
>- 數據處理指令大致可分為3類
>1.數據傳送指令
>2.算術邏輯運算運算
>3.比較指令
>- 數據處理指令只能對寄存器的內容進行操作,而不能對內存中的數據進行操作.所有ARM數據處理指令均可選擇使用S后綴,以使指令影響狀態標志
### 乘法指令
#### 乘法與乘加指令


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

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


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

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

##### 堆棧尋址續

#### 相對尋址
BL SUBR1//調用到SUBR1子程序
BEQ LOOP//條件跳轉到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.預處理:傻替換,條件編譯
>2.編譯:把C語言程序翻譯成匯編語言的程序編
>3.匯編:把每一條指令翻譯成二進制語句
>4.鏈接
預處理 編譯 匯編 鏈接
1.c 1.i 1.S 1.o 將1.o,2.o,3.o,庫文件 生成可執行的文件
2.c 2 .i 2.S 2.o
3.c 3.i 3.S 3.o
>- register int i;//如果有寄存器可用,則將i變量保存到寄存器中,不放在內存中,
>- register int &i//是錯誤的,因為不在內存里,所以沒有地址(以防可能有寄存器或無寄存器,都不要這樣寫)