Thumb微處理器的指令及應用

Download Report

Transcript Thumb微處理器的指令及應用

第七章
Thumb微處理器的指令及應用
DMATEK CO.,LTD
深圳市長高科技有限公司




本章節將介紹ARM 微處理器THUMB指令及其工作原理,一開始我們會先介紹為何要在
32位元指令中,再設計16位元的指令,並說明在那些應用中會使用到THUMB的工作模
式,最後我們詳細說明每個THUMB指令運作方式。
本章的主要內容有:
-
THUMB工作模式的應用時機
-
THUMB指令介紹
 7-1 Thumb微處理器指令描述與說明應用時機:
 為了相容資料匯流排寬度為16位元的應用系統,ARM體系結構除了支援執行效率
很高的32位元ARM指令集以外,同時還支援16位元的Thumb指令集。Thumb指令
集是通常使用的32位元ARM指令集的子集,每條Thumb指令是16位元長,Thumb
指令在標準的ARM暫存器下進行操作。執行時,16位元Thumb指令透明地即時解
壓成32位元ARM指令,並且沒有性能損失。這樣,以32位元處理器性能給出16位
元程式碼密度,在保留了32位程式碼優勢的同時,大大節省了儲存空間和成本。
 所有的Thumb指令都有對應的ARM指令,而且Thumb的編寫程式模型也對應於
ARM的編寫程式模型,在應用程式的編寫過程中,只要遵循一定的呼叫規則,
Thumb副程式和ARM副程式就可以互相呼叫。當處理器在執行ARM程式段時,稱
ARM處理器處於ARM工作狀態;當處理器在執行Thumb程式段時,稱ARM處理
器處於Thumb工作狀態。與ARM指令集相比較,Thumb指令集中的資料處理指令
的運算元仍然是32位元,指令位元址也為32位元,但Thumb指令集為實現16位元
的指令長度,捨棄了ARM指令集的一些特性,如大多數的Thumb指令是無條件執
行的,而幾乎所有的ARM指令都是有條件執行的;大多數的Thumb資料處理指令
的目的暫存器與其中一個來源暫存器相同。由於Thumb指令的長度為16位元,即
只用ARM指令一半的位元數來實現同樣的功能,所以,要實現特定的程式功能,
所需的Thumb指令的條數比ARM指令多。在一般的情況下,Thumb指令與ARM指
令的時間效率和空間效率關係如下:
- Thumb程式碼所需的儲存空間約為ARM程式碼的60%~70%;
- Thumb程式碼使用的指令數比ARM程式碼多約30%~40%;
- 若使用32位元的記憶體,ARM程式碼比Thumb程式碼快約40%;
- 若使用16位元的記憶體,Thumb程式碼比ARM程式碼快約40%~50%;
- 與ARM程式碼相比,使用Thumb程式碼,記憶體的功耗會降低約30%。
Thumb指令集與ARM指令集的區別主要有以下幾個方面:
- 分支指令。程式相對轉移,特別是條件分支指令與ARM的分支指令相比,在範圍
上有更多的限制,轉向副程式只具有無條件的轉移。
- 資料傳送指令。Thumb的資料處理指令對通用暫存器進行操作,在許多情況下,操
作的結果必須放入其中一個運算元暫存器中,而不是第三個暫存器中。另外,除
CMP指令外,存取R8~R15的Thumb資料處理指令不能更新旗標。
- 單暫存器寫/讀指令。在Thumb狀態下,這些指令只能存取暫存器R0~R7。
- 多暫存器寫/讀指令。採用PUSH和POP指令,以堆疊指標R13作為基址,實現
滿遞減堆疊。除可傳送R0~R7外,PUSH還可以儲存連接暫存器(R14),並且POP
可以載入程式指標(R15)。
- Thumb指令集沒有輔助運算器指令、信號量指令,以及存取CPSR或SPSR的指
令。
 顯然,ARM指令集和Thumb指令集各有其優點,若對系統的性能有較高要求,則應
使用32位元的儲存系統和ARM指令集;若對系統的成本及功耗有較高要求,則應使
用16位元的儲存系統和Thumb指令集。當然,若兩者結合使用,則可充分發揮其各
自的優點,會取得更好的效果。
 7-2 Thumb指令說明:
 7-12.1 記憶體存取指令
 (1) LDR和STR--常數偏移
 載入暫存器和儲存暫存器。記憶體的位址以一個暫存器的內容為基址加上常數偏移
量指明,其語法如下:
op Rd, [Rn, #immed_5x4]
opH Rd, [Rn, #immed_5x4]
opB Rd, [Rn, #immed_5x4]
 其中,H指明無符號半字元傳送的參數;B指明無符號位元組傳送的參數;Rd需載
入和儲存的暫存器,必須在R0~R7範圍內;immed_5xN為偏移量,這是一個運算
式,其取值是N的倍數,在0~31N範圍內。
 LDR指令用於從記憶體向暫存器載入一個字元、半字元或位元組;STR指令用於從
暫存器讀出一個字元、半字元和位元組儲存到記憶體中。Rn中的內容作為基址,再
加上偏移量形成運算元的位址。資料是無符號數,位元組或半字元載入到Rd的最低
有效位元組或半字元,其餘位元補0。字元傳送的位址必須可被4整除,半字元傳送
的位址必須可被2整除。
 例如:
LDR R3, [R5, #0
STRB R0, [R3, #31]
STRH R7, [R3, #16]
LDRB R2, [R4, #label{PC}]
 (2) LDR和STR—暫存器偏移
 載入暫存器和儲存暫存器。記憶體的位址以一個暫存器的內容為基址加上暫存
器偏移量指明,其語法如下:
op Rd, [Rn, Rm]
 其中,op是下列情況之一:
-LDR,載入暫存器,4位元組字元;
-STR,儲存暫存器,4位元組字元;
-LDRH,載入暫存器,2位元組無符號半字元;
-LDRSH,載入暫存器,2位元組帶符號半字元;
-STRH,儲存暫存器,2位元組半字元;
-LDRB,載入暫存器,無符號位元組;
-LDRSB,載入暫存器,帶符號位元組;
-STRB,儲存暫存器,位元組;
-Rm,內含偏移量的暫存器,Rm必須在R0~R7範圍內。
 STR指令將Rd中的一個字元、半字元或位元組儲存到記憶體,LDR指令從記憶體中
將一個字元、半字元或位元組載入到Rd中。指令中Rn的內容為基址加上Rm中的偏
移量形成記憶體的位址。對於無符號位元數的載入,Rd的其餘位補0;對於帶符號
位元數的載入,Rd的其餘位元複製符號位元。

例如:
LDR R2, [R1, R5]
LDRSH R0, [R0, R6]
STRB R1, [R7, R0]
 (3) LDR和STR-PC或SP相對偏移
 載入暫存器和儲存暫存器。用PC或SP中值加上常數偏移量指明記憶體位址,其語
法如下:
LDR Rd, [PC, #immed_8×4]
LDR Rd, label
LDR Rd, [SP, #immed_8×4]
STR Rd, [SP, #immed_8×4]
 其中,immed_8×4為偏移量,這是一個運算式,取值為4的整數倍,範圍在0~
1020內;Label是程式相對偏移運算式,Label必須在當前指令之後且在1KB範圍內
;PC或SP的基址加上常數偏移量形成記憶體位址,PC的位元[1]忽略,確保了地
址是字元對準的。STR指令沒有PC相對偏移的形式。
 例如:
LDR R2, [PC, #1016]
LDR R5, localdata
LDR R0, [SP, #920]
STR R1, [SP, #20]
 (4) PUSH和POP
 暫存器R0~R7及LR進和暫存器R0~R7及PC出,其語法如下:
PUSH{reglist)
POP {reglist]
PUSH{reglist,LR)
POP {reglist,PC)
 其中,reglist為R0~R7範圍內的暫存器列表,暫存器間用逗號隔開。指令中的括弧{}
與前述不同,它是指令格式的一部分,而不代表暫存器列表可選,暫存器列表中至少
有一個暫存器。
 Thumb的堆疊找是採用滿遞減堆疊。堆疊向下生長成長,並且SP指向堆疊的最後入口
處。暫存器以數位依編號順序儲存在堆疊中,最低數位編號最低的暫存器其位址最低
。
 POP{reglist,PC)引起處理器轉移到從堆疊彈出給PC的位址處,這通常是從副程
式返回,之前LR應在副程式開頭壓入堆疊。這些指令不影響條件碼旗標。
 例如:
PUSH{R0, R3, R5 }
PUSH{R1, R4-R7}
PUSH{R0, LR}
POP {R2, R5}
POP {R0-R71}

(5) LDMIA和STMIA
 載入和儲存多個暫存器,其語法如下:
op Rn!,{reglist}
 其中,reglist為R0~R7範圍內的暫存器列表,暫存器間用逗號隔開。暫存器列表中
至少有一個暫存器。暫存器以數位依編號順序載入或儲存,最低數位編號最低的暫存
器在Rn的初始位址中。Rn中的值以reglist列表中暫存器個數的4倍增加。若Rn在暫存
器列表中,則對於LDMIA指令,Rn的最終值是載入的值,不是增加後的地址;對於
STMIA指令,Rn的儲存值有兩種情況:
 若Rn是暫存器列表中最低數位編號最低的暫存器,則Rn儲存的值為Rn的初值;
 其他情況則不可預知。

例如:
LDMIA R3!, {R0, R4}
LDMIA R5!, {R0-R7}
STMIA R0!, {R6, R7}
STMIA R3!, {R3, R5, R7}
 7-12.2 資料處理指令
 (1) ADD和SUB—低暫存器(R0~R7)

op
op
op








加法和減法。對於低暫存器操作,這兩條指令各有3種形式,其語法如下:
Rd, Rn, Rm
Rd, Rn, #expr3
Rd, #expr8
其中:
Rd,目的暫存器,在“op Rd,#expr8”形式的指令中也作為第一運算元;
Rn,第一運算元暫存器;
Rm,第二運算元暫存器;
expr3,運算式,其取值為-7~+7範圍內的整數;
expr8,運算式,其取值為-255~+255範圍內的整數;
“opRd,Rn,Rm”形式指令執行Rn+Rm或Rn-Rm操作,結果放在Rd中;
“op Rd,Rn,#expr3”形式指令執行Rn+expr3或Rn-expr3操作,結果放在Rd中
;
 “opRd,#expr8”形式指令執行Rd+expr8或Rd-expr8操作,結果放在Rd中。
 若expr3或expr8為負值的ADD指令,則在組譯時被組譯成對應的帶正數常數的
SUB指令;若expr3或expr8為負值的SUB指令,則在組譯時被組譯成對應的帶正
數常數的ADD指令,這些指令將根據結果更新旗標N、Z、C和V。
 例如:
ADD R3, R1, R5
SUB R0, R4, #5
ADD R7, #201
 (2) ADD--高或低暫存器
 將暫存器中的值相加,結果送回到第一運算元暫存器,其語法如下:
ADD Rd, Rm
 這條指令完成Rd+Rm,結果放到Rd中。若Rd和Rm均為低暫存器,指令將根據執
行結果更新旗標N、Z、C和V,其他情況下旗標不變。
 例如:

(3) ADD和SUB-SP
 SP暫存器加或減常數,其語法如下:
op SP, #expr
 其中,expr為運算式,取值為-508~+508範圍內4的整數倍。
 該指令把SP暫存器中的值加上常數expr,結果放入SP暫存器中。指令執行結果不影
響條件碼旗標。
 例如:
ADD SP, #31
SUB SP, #96
SUB SP, abc+8 :abc+8的結果必須為-508~+508範圍內4的整數倍
 (4) ADD-PC和SP
 PC或SP暫存器加一常數,結果放入低暫存器。其語法如下:
op
Rd, Rp, #expr
ADD R12, R4
ADD R10, R11
ADD R2, R4 ;等價於ADD R2,R2,R4
 其中,expr為運算式,取值為0~1020範圍內4的整數倍。
Rp PC或SP
 該指令把Rp暫存器中的值加上常數expr,結果放入Rd暫存器中。若Rp是PC暫存器
,則使用的第一運算元值是(當前指令位元址+4)AND OxFFFFFFFC,指令執行結果
不影響條件碼旗標。
 例如:
ADD R6, SP, #64
ADD R2, PC, #980
ADD R0, PC, lit-{PC) ;lit-{PC)的結果必須是0~1020範圍內4的整數倍

(5) ADC、SBC和MUL
 帶進位位元的加法、帶進位位元的減法和乘法。其語法如下:
Op Rd,Rm
 其中,Rd是目的暫存器,也是第一個運算元暫存器;Rm是第二個運算元暫存器
。Rd和Rm必須是低暫存器(R0~R7)。
 ADC指令完成Rd+Rm,再加進位,結果放入Rd中,用這一條指令可組合成多字
元加法。SBC指令完成Rd-Rm,再減相應的借位,結果放入Rd中,用這一條指令
可組合成多字元減法。MUL指令完成RdxRm,結果放入Rd中。
 ADC和SBC指令將根據結果更新旗標N、Z、C和V;MUL指令將根據結果更新旗
標N和Z,會使C和V不可靠。
 例如:
ADC R2, R4
 (6) AND、ORR、EOR和BIC
 按位元邏輯操作,其語法如下:
op Rd, Rm
 其中,Rd是目的暫存器,它也是第一運算元暫存器,Rd必須在R0~R7範圍內。
Rm是第二運算元暫存器,Rm必須在R0~R7範圍內。
 這些指令用於對Rd和Rm中的值進行按位元邏輯操作,結果放在Rd暫存器中。
AND指令進行邏輯“與”操作,ORR指令進行邏輯“或”操作,EOR指令進行邏
輯“互斥或”操作,BIC指令進行“Rd AND NOT Rm”操作。這些指令將根據執
行結果更新旗標N和Z。
 例如:
AND R2, R4
 (7) ASR、I.SL、LSR和ROR
 移位和迴圈移位操作,其語法如下:
op
Rd, Rs
op
Rd, Rm, #expr
 其中,op操作碼,為下列之一:
-ASR算術右移。將來源暫存器中的內容看做補數形式的帶符號整數,將符號位元複
製到空位;
-LSL邏輯左移。空位清為零;
-LSR邏輯右移。空位清為零;
-ROR迴圈右移。將來源暫存器的最低位移出後,再迴圈移到最高位。ROR僅能有暫
存器控制的移位形式(即上面第一種形式)。
 expr,常數移位量,它是一個取值為整數的運算式。整數的範圍如下:
-若op是LSR,則其為0~31;
-其他情況則為1~32。
 若是暫存器控制移位元時,這些指令從Rd中取值,並對其進行移位,結果放回Rd中
,Rs的最低有效位元組用做移位元量來控制移位。除ROR外,其他指令有:
-若移位量為32,則Rd清為零,最後移出的位元保留在旗標C中;
-若移位量大於32,則Rd和旗標C均被清為零。
 對於常數控制移位元形式,指令從Rm中取數,並對其進行移位,結果放到Rd中。
 這些指令根據執行結果更新旗標N和Z,但不影響旗標V。對於旗標C,若移位元量是
零,則不受影響;在其他情況下,則是來源暫存器的最後移出位。
 例如:
ASR R3,R5
LSR R0,R2,#6
LSR R0, R4, #0
 (8) CMP和CMN
 比較和比較負值,其語法如下:
CMP
Rn, #expr
CMP
Rn, Rm
CMN
Rn, Rm
 其中,expr為運算式,其值範圍為0~255內的整數。
 這些指令執行後將根據結果更新條件碼旗標,但不往暫存器中存放結果。CMP指令
從Rn中減去expr或Rm的值,CMN指令將Rn和Rm的值相加。對於“CMP Rn,
#expr”和“CMN Rn,Rm”指令,Rn和Rm必須是R0~R7之一;對於“CMP Rn,
Rm”指令,Rn和Rm則可以是R0~R15中的任何暫存器。
 例如:
CMP
CMP
CMN
R2, #255
R7, R12
R1, R5
 (9) MOV、MVN和NEG
 傳送、傳送非和取負,其語法如下:
MUV
Rd, #expr
MOV
Rd, Rn
MVN
Rd, Rm
NEG
Rd, Rm
 其中,expr為運算式,其值範圍為0~255內的整數。
 MOV指令將expr或Rm中的值放入Rd;MVN指令從Rm中取值,然後對該值進行按
位元邏輯“非”操作,結果放入Rd;NEG指令取Rm的值再乘以-1,結果放入Rd
。對於“MOV Rd,#expr”、“MVN Rd,Rm”和“NEG Rd,Rm”指令,Rd和Rm
必須在R0~R7範圍內;對於“MOV Rd,Rm”指令,Rd和Rm可以是R0~R15中
的任何一個。
 “MOV Rd,#expr”和“MVN Rd,Rm”指令根據結果更新旗標N和Z,但對旗標C和
V無影響;“NEG Rd,Rm”指令根據結果更新旗標N、Z、C和V;“MOV Rd,Rm”
指令對旗標位元的影響有兩種情況:
 若Rd或Rm是高暫存器(R8~R15),則不影響旗標位元。
 若Rd和Rm是低暫存器(R0~R7),則根據執行結果更新旗標N和Z,並且清除旗標C
和V。
 例如:
MOV
MOV
MVN
NEG
R3, #0
R0, R12
R7, R1
R2, R2
 (10) TST
 測試位。其語法如下:
TST
Rn, Rm
 其中,Rn是第一運算元暫存器,Rm是第二運算元暫存器,Rn和Rm必須是R0~
R7暫存器。
 TST指令對Rm和Rn中的值進行按位“AND”操作。它根據執行結果更新旗標N和Z
,但不影響旗標C和V,並且不保留結果。
 例如:
TST
R2, R4
 7-12.3 分支指令
 (1) B
 分支指令。這是Thumb指令集中唯一的有條件指令。其語法如下:
B {cond} label
 其中,label是程式相對偏移運算式,通常是在同一程式碼段內的標號,其要求如下
:
 若使用cond,則label必須在當前指令的-252~+256位元組範圍內;
 若指令是無條件的,則label必須在+2KB範圍內。
 若條件cond滿足或不使用條件cond,則B指令引起處理器轉移到label,label必須在
指定的限制內。Thumb指令集的條件碼與ARM指令集的相同。
 例如:
B dloop
BEG sectB
 (2) BL
 帶鏈結的長分支指令,其語法如下:
BL label,
 其中,label是程式相對偏移運算式。
 BL指令將下一條的位址複製到R14(連接暫存器(LR)),並使處理器轉移到label指
定的指令處。
 例如:
BL extract
 (3) BX
 分支指令,並可選地交換指令集。其語法如下:
BX Rm
 其中,Rm裝有分支目的地址,Rm的位[0]不用於位元址部分,若Rm的位元[0]清為零
,則其位[1]也必須清為零,並且指令清除CPSR中的旗標T,目的地址的程式碼被解
釋為ARM程式碼;
 若Rm的位[0]設置,則目的地址的程式碼被解釋為Thumb程式碼。
 例如:
BX K5
 (4) BLX
 帶鏈結分支指令,並可選地交換指令集。其語法如下:
BLX Rm
BLX label
 其中,Rm裝有分支目的地址,Rm的位[0]不用於位元址部分,若Rm的位元[0]清為零
,則其位[1]也必須清為零,並且指令清除CPSR中的旗標T,目的地址的程式碼被解釋
為ARM程式碼。




BLX指令的作用如下:
複製下一條指令的位元址到R14;
引起處理器轉移到label或Rm儲存的位址;
如果Rm的位[0]清為零,或使用“BLX label”形式,則指令集切換到ARM狀態。
 例如:
BLX R6
BLX armsub
 7-12.4 中斷和中斷點指令
 (1) SWI
 軟體中斷指令,其語法如下:
SWI immed_8
 其中,immed_8為數字運算式,其取值為0~255範圍內的整數。
 SWI指令引起SWI異常,這意味著處理器狀態切換到ARM狀態,處理器模式切換到
管理模式,CPSR保存到管理模式的SPSR中,程式執行轉移到SWI向量位址。
 處理器忽略immed_8,但immed_8出現在指令操作碼位元[7:0]中,而異常處理程
式用它來確定正在請求何種服務。這條指令不影響條件碼旗標。
 例如:
SWI 12
 (2) BKPT
 中斷點指令,其語法如下:
BKPT immed_8
 其中,immed_8為數字運算式,其取值為0~255範圍內的整數。
 BKPT指令引起處理器進入除錯模式,除錯工具利用這一點來調查當到達特定位元
址的指令時的系統狀態。
 處理器忽略immed_8,但immed_8出現在指令操作碼位元[7:0]中,除錯器用它來
保存有關中斷點的附加資訊。
 例如:
BKPT 67
BKPT 210110
 7-12.5 Thumb虛擬指令
 (1) ADR
 該指令將程式相對偏移位址載入到暫存器中,其語法如下:
ADR register,expr
 其中,register為載入的暫存器。expr為程式相對偏侈運算式,偏移量必須是正數並小
於1KB。expr必須局部定義,不能被導入。
 在Thumb狀態,ADR僅可以產生字元對準位元址,使用ALIGN指令來確保expr是對準
的。expr必須賦值成與ADR虛擬指令在同一個程式碼區域的位址,若它在另一個程式
碼區域,則不能保證位址鏈結後會在指令範圍內。
 例如:
ADR R4, exampl
;code
ALlGN
example DCW 0, 0, 0, 0
;=>ADD R4,PC,#nn
 (2) LDR
 該指令用32位元常數或一個位址載入一個低暫存器,其語法如下:
LDR register,=[expr | label-exp]
 其中,register為載入的暫存器,僅可以是R0~R7暫存器。
 expr賦值成數字常數:
- 若expr值在MOV指令範圍內,則組譯器產生指令;
- 若expr值不在MOV指令範圍內,則組譯器將常數放入文字區塊,並產生一條程式
相對偏移的LDR指令,從文字區塊中讀常數。
Label-exp,程式相對偏移或外部運算式。
LDR虛擬指令用於兩個主要目的:
- 當常數由於超出MOV指令範圍不能載入到暫存器中時,產生文字常數;
- 將程式相對偏移或外部位址載入到暫存器中,位址保持有效,與鏈結器將包含
LDR的ELF區域放到何處無關。
LDR R1, =0XFFF ;載入0xFFF到Rl中
LDR R2, =labelname ;將labdname的地址載入到R2中
 (3) NOP
 該指令產生所需的ARM無操作程式碼,其語法如下:
NOP
 狀態旗標不受NOP指令影響。
 7-3 問題與討論:




一、 請說明使用THUMB的使用時機。
二、為何THUMB並沒有支援有條的執行。
三、執行那道指令可以從ARM工作狀態切換到THUMB工作狀態。
四、執行那道指令可以從THUMB工作狀態切換到ARM工作狀態。