ARM手冊中都會有一些Programmers’ Model章節(jié)。那么什么是Programmers’ Model,Programmers’ Model是從編程者的角度來看,處理器提供了哪些可用的特性給編程人員。這里以ARM7TDMI-S 為基礎(chǔ)來介紹一些基本的模型,對最新的內(nèi)核也適用。想了解最新的可以參閱ARMv8-A的架構(gòu)手冊,里面可以看到有應(yīng)用級和系統(tǒng)級的Programmers’ Model(分別有64位架構(gòu)和32位架構(gòu)的),有很多的特性。
數(shù)據(jù)類型
ARM7TDMI-S 可以支持下列的數(shù)據(jù)類型
- Byte(字節(jié),8位)
- Halfword(半字,16位,以兩字節(jié)為對齊邊界)
- Word(字,32位,以四字節(jié)為對齊邊界)
處理器運行狀態(tài)
處理器在運行時處于下面兩種狀態(tài)之一:
- ARM狀態(tài),運行32位,四字節(jié)對齊的ARM指令
-THUMB狀態(tài),運行16位,兩字節(jié)對齊的THUMB指令
需要注意的是兩種狀態(tài)的之間的切換并不會影響到寄存器的內(nèi)容和處理器的模式。
切換狀態(tài)
可以通過BX指令進(jìn)行切換,格式如下:
Thumb state:
BX Rn
ARM state:
BX{condition} Rn
Rn可以是任何寄存器。也可以是PC寄存器,但是不建議,因為有可能導(dǎo)致非預(yù)期的結(jié)果,比如跳轉(zhuǎn)到非對齊的地址。
進(jìn)入THUMB狀態(tài)有兩種方式
- 通過BX Rn指令進(jìn)行切換,如下圖所示,Rn最低位是1時,通過BX Rn就切換到THUMB狀態(tài),為什么可以這樣操作,因為不管是THUMB狀態(tài)(地址2字節(jié)對齊)或者是ARM狀態(tài)(地址四字節(jié)對齊)都不允許跳轉(zhuǎn)到一個非對齊的地址,作為地址時Rn的最低位是被忽略的。這樣就可以通過BX和Rn的最低有效位來判斷跳轉(zhuǎn)時跳到ARM狀態(tài)(bit0為0),還是THUMB狀態(tài)(最低有效位為1)
- 通過異常還回時自動進(jìn)入THUMB狀態(tài)。因為異常狀態(tài)都是ARM狀態(tài),當(dāng)處在THUMB狀態(tài)時觸發(fā)了異常狀態(tài),會自動切換到ARM狀態(tài),而異常還回時,會自動還回到THUMB狀態(tài)。

同理進(jìn)入進(jìn)入ARM狀態(tài)也有兩種方式,第一種是通過BX Rn,Rn的最低有效位是0。或者在觸發(fā)異常時,自動切換入ARM狀態(tài)(這種情況,PC會被自動保存到進(jìn)入的異常模式對應(yīng)的鏈接寄存器,并且指令從異常向量對應(yīng)的地址開始執(zhí)行)
指令長度
ARM狀態(tài)指令是32位,THUMB狀態(tài)指令是16位的
存儲格式
ARM7TDMI-S 支持大端和小端兩種存儲格式(如何解釋存儲在存儲器中的word)
- 大端格式:最低的地址存儲字的最高字節(jié)
- 小端格式:最低的地址存儲字的最低字節(jié)
操作模式

模式的切換可以通過軟件的方式控制,也可以由外部中斷/異常引起。大部分應(yīng)用程序執(zhí)行在User模式。除了User模式,其他模式都處于特權(quán)模式。特權(quán)模式為中斷/異常異常服務(wù)的,以獲得對受保護的資源的訪問。
寄存器
ARM7TDMI-S總共有如下寄存器:
- 30個通用寄存器,可存儲任何值(數(shù)據(jù)/地址)
- 6個狀態(tài)寄存器
- 1個PC寄存器
備注:這些寄存器是32位的,并且有處理器狀態(tài)和操作模式?jīng)Q定哪些寄存器可供編程者使用。
ARM狀態(tài)的寄存器組織結(jié)構(gòu)如下圖所示:

在ARM狀態(tài)任何時候都可以看到R0~R15、CPSR這些寄存器
幾個用于特殊用途的寄存器,包括R13,R14
- R13:用作堆棧指針SP,存儲堆棧在內(nèi)存中的地址,每個模式都有自己的堆棧指針(除了system和user共享一個堆棧指針)
- R14:用來存儲子程序還回地址和異常還回地址,通常稱為鏈接寄存器LR。具體是執(zhí)行BL子程序跳轉(zhuǎn)或者發(fā)生異常時時自動把PC值存儲到R14。
- R15:持有程序計數(shù)器(PC)。在ARM狀態(tài)R15的bits [1:0] 是0,在THUMB狀態(tài),R15的bit [0],其他位則保存PC值。
- CPSR/SPSR:主要保存了模式位和條件碼標(biāo)志。
備注:ARM7TDMI是流水線架構(gòu),如下圖所示:

這意味著在一個機器周期中一個指令被提?。╢etch),另一個指令被解碼(decode),而另一個指令被執(zhí)行(execute)。而PC存儲的是正在fetch的指令地址,而不是正在執(zhí)行的地址。通常編程人員不需要訪問PC寄存器,除非需要一些特殊的操作,比如從異?;謴?fù),在內(nèi)存中進(jìn)行遠(yuǎn)距離跳轉(zhuǎn)。
THUMB狀態(tài)的寄存器是ARM狀態(tài)的一個子集,寄存器組織結(jié)構(gòu)如下圖所示:

能直接訪問的寄存器只有 R0–R7,PC,SP,LR,CPSR及對應(yīng)模式分組備份寄存器(圖中帶三角形陰影部分)
ARM狀態(tài)和THUMB狀態(tài)寄存器映射關(guān)系見下圖:

備注: 在THUMB狀態(tài),R8–R15 (Hi registers)訪問受限(只有MOV,ADD和CMP指令可訪問)。
程序狀態(tài)寄存器
ARM7TDMI-S有一個CPSR+5個SPSR(異常模式使用),這些寄存器:
- 保存最近執(zhí)行的ALU操作的信息
- 控制使能/禁用中斷(IRQ/FIQ)
- 設(shè)置處理器的狀態(tài)
- 設(shè)置處理器的操作模式
CPSR/SPSR的格式如下圖

CPSR/SPSR有兩大塊重要的域:
- 標(biāo)志(flags):包含條件標(biāo)志
- 控制(control):包含處理器的狀態(tài),模式,中斷掩碼位
所有的cpsr位域都可以在特權(quán)模式被讀/寫。
在用戶模式只有flags域可以被寫,但其他域都是可以讀的。
Condition code ?ags
? N = ALU運算為負(fù)數(shù)( Negative)
? Z = ALU運算結(jié)果為0(Zero)
? C = ALU運算結(jié)果進(jìn)位(Carried out)
? V = ALU運算結(jié)果溢出(Ver?owed)
備注:這些位在算術(shù)或者邏輯操作之后可能改變,在ARM狀態(tài)指令可以被有條件的執(zhí)行,這些位可以用來測試一條指令是否可以執(zhí)行。但在THUMB狀態(tài)只有分支指令才具備條件執(zhí)行的能力
control bits
- I = 1: 禁止 IRQ
- F = 1: 禁止 FIQ
- T = 0: 處理器處于ARM狀態(tài)
T = 1: 處理器處于Thumb狀態(tài)
備注:軟件不應(yīng)該去改變CPSR中的T位,否則處理器會產(chǎn)生非預(yù)期的結(jié)果。
模式位如下表所示,在表中未出現(xiàn)的值不應(yīng)該被使用,否則會出現(xiàn)進(jìn)入不可恢復(fù)的狀態(tài),只能復(fù)位系統(tǒng):

異常
異常向量入口地址如下表所示:

- 異常的優(yōu)先級
當(dāng)有多個異常同時出現(xiàn)時,有固定的優(yōu)先級,系統(tǒng)用它來確定那個異常先處理:
如下所示,從上往下優(yōu)先級越來越低:
1 Reset
2 Data abort
3 FIQ
4 IRQ
5 Prefetch abort
6 Undefined Instruction, Software interrupt.
備注:并不是所有的異常都能同時發(fā)生,6中的Undefined Instruction和Software interrupt 沒法同時發(fā)生
發(fā)生異常時處理流程:
(1)保存下一條要執(zhí)行的指令到LR_<mode>
(2)復(fù)制CPSR到SPSR_<mode>
(3)設(shè)置適當(dāng)?shù)腃PSR位:
1)切換到ARM狀態(tài)
2) 切換到對應(yīng)的異常模式
3) 禁用中斷(如果需要)
(4)強制PC從相關(guān)的異常向量中去獲取下一條指令中斷還回時的處理流程
(1)從LR_<mode>中恢復(fù)PC的值(LR_<mode>需要適當(dāng)?shù)臏p去一個偏移量,視中斷類型而定)
(2)從SPSR_<mode>中恢復(fù)CPSR的值
(3)使能中斷(如果進(jìn)入的時候禁用掉的話)
備注:異常處理只能在ARM狀態(tài)進(jìn)行處理,如果異常之前是THUMB狀態(tài),發(fā)生異常時會自動切換到ARM狀態(tài),異常處理完會自動切換回THUMB狀態(tài),不需要手動去處理。
- Reset流程
(1)當(dāng)nRESET信號變?yōu)榈碗娖降臅r候,ARM7TDMI-S 放棄正在執(zhí)行的指令。
(2)當(dāng)nRESET信號再次變?yōu)楦唠娖綍r,ARM7TDMI-S會:
1)用當(dāng)前的PC和CPSR值覆蓋掉 R14_svc 和 SPSR_svc。但是存儲的PC和SPSR值是未定義的。
2)對CPSR進(jìn)行操作,包括:設(shè)置M[4:0]的值為10011 (Supervisor mode),置位 I 和 F,清除 T 位
3)強制PC從地址0獲取下一條指令
4)從ARM狀態(tài)中恢復(fù)執(zhí)行
參考文獻(xiàn)
【1】ARM7TDMI-S Programmer’s Model
【2】ARM Assembly Language Fundamentals and Techniques (2nd ed.)