今天小編要和大家分享的是Thumb指令分類 Thumb指令特點,接下來我將從Thumb指令分類,Thumb指令特點,Thumb狀態切換,Thumb數據處理指令,這幾個方面來介紹。

Thumb指令分類 Thumb指令特點

Thumb指令集是ARM指令集的一個子集,是針對代碼密度問題而提出的,它具有16位的代碼寬度。與等價的32位代碼相比較,Thumb指令集在保留32位代碼優勢的同時,大大的節省了系統的存儲空間。Thumb不是一個完整的體系結構,不能指望處理器只執行Thumb指令集而不支持ARM指令集。

Thumb指令分類,Thumb指令特點,Thumb數據處理指令等信息資料

Thumb指令分類

Thumb指令集分為:分支指令、數據傳送指令、單寄存器加載和存儲指令以及多寄存器加載和存儲指令。Thumb指令集沒有協處理器指令、信號量(semaphore)指令以及訪問CpSR或SpSR的指令。

1.存儲器訪問指令

(1)DR和STR--立即數偏移

加載寄存器和存儲寄存器。存儲器的地址以一個寄存器的立即數偏移(immediateoffset)指明。

指令格式:

opRd,[Rn,#immed_5×4]

opHRd,[Rn,#immed_5×2]

opBRd,[Rn,#immed_5×1]

其中:

op:為DR或STR。

H:指明無符號半字傳送的參數。

B:指明無符號字節傳送的參數。

Rd:加載和存儲寄存器。Rd必須在R0~R7范圍內。

Rn:基址寄存器。Rn必須在R0~R7范圍內。

immed_5×N:偏移量。它是一個表達式,其取值(在匯編時)是N的倍數,在(0~31)*N范圍內,N=4、2、1。

STR:用于存儲一個字、半字或字節到存儲器中。

DR:用于從存儲器加載一個字、半字或字節。

Rn:Rn中的基址加上偏移形成操作數的地址。

立即數偏移的半字和字節加載是無符號的。數據加載到Rd的最低有效字或字節,Rd的其余位補0。

字傳送的地址必須可被4整除,半字傳送的地址必須可被2整除。

指令示例:

DRR3,[R5,#0]

STRBR0,[R3,#31]

STRHR7,[R3,#16]

DRBR2,[R4,#1abe-{pC}]

(2)DR和STR--寄存器偏移

加載寄存器和存儲寄存器。用一個寄存器的基于寄存器偏移指明存儲器地址。

指令格式:

opRd,[Rn,Rm]

其中,op是下列情況之一:

DR:加載寄存器,4字節字。

STR:存儲寄存器,4字節字。

DRH:加載寄存器,2字節無符號半字。

DRSH:加載寄存器,2字節帶符號半字。

STRH:存儲寄存器,2字節半字。

DRB:加載寄存器,無符號字節。

DRSB:加載寄存器,帶符號字節。

STRB:存儲寄存器,字節。

Rm:內含偏移量的寄存器,Rm必須在R0~R7范圍內。

帶符號和無符號存儲指令沒有區別。

STR指令將Rd中的一個字、半字或字節存儲到存儲器。

DR指令從存儲器中將一個字、半字或字節加載到Rd。

Rn中的基址加上偏移量形成存儲器的地址。

寄存器偏移的半字和字節加載可以是帶符號或無符號的。數據加載到Rd的最低有效字或字節。對于無符號加載,Rd的其余位補0;或對于帶符號加載,Rd的其余位復制符號位。字傳送地址必須可被4整除,半字傳送地址必須可被2整除。

指令示例:

DRR2,[R,R5]

DRSHR0,[R0,R6]

STRBR,[R7,R0]

(3)DR和STR--pC或Sp相對偏移

加載寄存器和存儲寄存器。用pC或Sp中值的立即數偏移指明存儲器中的地址。沒有pC相對偏移的STR指令。

指令格式:

DRRd,[pC,#immed_8×4]

DRRd,[abe

DRRd,[[Sp,#immed_8×4]

STRRd,[Sp,#immed_8×4]

其中:

immed_8×4:偏移量。它是一個表達式,取值(在匯編時)為4的整數倍,范圍在0~1020之間。

abe:程序相對偏移表達式。abe必須在當前指令之后且1KB范圍內。

STR:將一個字存儲到存儲器。

DR:從存儲器中加載一個字。

pC或Sp的基址加上偏移量形成存儲器地址。pC的位[1]被忽略,這確保了地址是字對準的。字或半字傳送的地址必須是4的整數倍。

指令示例:

DRR2,[pC,#1016]

DRR5,ocadata

DRR0,[Sp,#920]

STRR,[Sp,#20]

(4)pUSH和pOp

低寄存器和可選的R進棧以及低寄存器和可選的pC出棧。

指令格式:

pUSH{regist}

pOp{regist}

pUSH{regist,R}

pOp{regist,pC}

其中:

regist:低寄存器的全部或其子集。

括號是指令格式的一部分,它們不代表指令列表可選。列表中至少有1個寄存器。Thumb堆棧是滿遞減堆棧,堆棧向下增長,且Sp指向堆棧的最后入口。寄存器以數字順序存儲在堆棧中。最低數字的寄存器存儲在最低地址處。

pOp{regist,pC}這條指令引起處理器轉移到從堆棧彈出給pC的地址,這通常是從子程序返回,其中R在子程序開頭壓進堆棧。這些指令不影響條件碼標志。

指令示例:

pUSH{R0,R3,R5}

pUSH{R1,R4-R7}

pUSH{R0,R}

pOp{R2,R5}

pOp{R0-R7,pC}

(5)DMIA和STMIA

加載和存儲多個寄存器。

指令格式:

opRn!,{regist}

其中,op為DMIA或STMIA。

regist為低寄存器或低寄存器范圍的、用逗號隔開的列表。括號是指令格式的一部分,它們不代表指令列表可選,列表中至少應有1個寄存器。寄存器以數字順序加載或存儲,最低數字的寄存器在Rn的初始地址中。

Rn的值以regist中寄存器個數的4倍增加。若Rn在寄存器列表中,則:

對于DMIA指令,Rn的最終值是加載的值,不是增加后的地址。

對于STMIA指令,Rn存儲的值有兩種情況:若Rn是寄存器列表中最低數字的寄存器,則Rn存儲的值為Rn的初值;其他情況則不可預知,當然,regist中最好不包括Rn。

指令示例:

DMIAR3!,{R0,R4}

DMIAR5!,{R0~R7}

STMIAR0!,{R6,R7}

STMIAR3!,{R3,R5,R7}

2.數據處理指令

(1)ADD和SUB--低寄存器

加法和減法。對于低寄存器操作,這2條指令各有如下3種形式:

兩個寄存器的內容相加或相減,結果放到第3個寄存器中。

寄存器中的值加上或減去一個小整數,結果放到另一個不同的寄存器中。

寄存器中的值加上或減去一個大整數,結果放回同一個寄存器中。

指令格式:

opRd,Rn,Rm

opRd,Rn,#expr3

opRd,#expr8

其中:

op為ADD或SUB。

Rd:目的寄存器。它也用做“opRd,#expr8”的第1個操作數。

Rn:第一操作數寄存器。

Rm:第二操作數寄存器。

expr3:表達式,為取值在-7~+7范圍內的整數(3位立即數)。

expr8:表達式,為取值在-255~+255范圍內的整數(8位立即數)。

“opRd,Rn,Rm”執行Rn+Rm或Rn-Rm操作,結果放在Rd中。

“opRd,Rn,#expr3”執行Rn+expr3或Rn-expr3操作,結果放在Rd中。

“opRd,#expr8”執行Rd+expr8或Rd-expr8操作,結果放在Rd中。

expr3或expr8為負值的ADD指令匯編成相對應的帶正數常量的SUB指令。expr3或expr8為負值的SUB指令匯編成相對應的帶正數常量的ADD指令。

Rd、Rn和Rm必須是低寄存器(R0~R7)。

這些指令更新標志N、Z、C和V。

指令示例:

ADDR3,R,R5

SUBR0,R4,#5

ADDR7,#201

(2)ADD--高或低寄存器

將寄存器中值相加,結果送回到第一操作數寄存器。

指令格式:

ADDRd,Rm

其中:

Rd:目的寄存器,也是第一操作數寄存器。

Rm:第二操作數寄存器。

這條指令將Rd和Rm中的值相加,結果放在Rd中。

當Rd和Rm都是低寄存器時,指令“ADDRd,Rm”匯編成指令“ADDRd,Rd,Rm”。若Rd和Rm是低寄存器,則更新條件碼標志N、Z、C和V;其他情況下這些標志不受影響。

指令示例:

ADDR12,R4

(3)ADD和SUB--Sp

Sp加上或減去立即數常量。

指令格式:

ADDSp,#expr

SUBSp,#expr

其中:expr為表達式,取值(在匯編時)為在-508~+508范圍內的4的整倍數。

該指令把expr的值加到Sp的值上或用Sp的值減去expr的值,結果放到Sp中。

expr為負值的ADD指令匯編成相對應的帶正數常量的SUB指令。expr為負值的SUB指令匯編成相對應的帶正數常量的ADD指令。

這條指令不影響條件碼標志。

指令示例:

ADDSp,#32

SUBSp,#96

(4)ADD--pC或Sp相對偏移

Sp或pC值加一立即數常量,結果放入低寄存器。

指令格式:

ADDRd,Rp,#expr

其中:

Rd:目的寄存器。Rd必須在R0~R7范圍內。

Rp:Sp或pC。

expr:表達式,取值(匯編時)為在0~1020范圍內的4的整倍數。

這條指令把expr加到Rp的值中,結果放入Rd。

若Rp是pC,則使用值是(當前指令地址+4)AND&FFFFFFC,即忽略地址的低2位。

這條指令不影響條件碼標志。

指令示例:

ADDR6,Sp,#64

ADDR2,pC,#980

(5)、SBC和MU

帶進位的加法、帶進位的減法和乘法。

指令格式:

opRd,Rm

其中:

op為ADC、SBC或MU。

Rd:目的寄存器,也是第一操作數寄存器。

Rm:第二操作數寄存器,Rd、Rm必須是低寄存器。

ADC將帶進位標志的Rd和Rm的值相加,結果放在Rd中,用這條指令可組合成多字加法。

SBC考慮進位標志,從Rd值中減去Rm的值,結果放入Rd中,用這條指令可組合成多字減法。

MU進行Rd和Rm值的乘法,結果放入Rd中。

Rd和Rm必須是低寄存器(R0~R7)。

ADC和SBC更新標志N、Z、C和V。MU更新標志N和Z。

在ARMv4及以前版本中,MU會使標志C和V不可靠。在ARMv5及以后版本中,MU不影響標志C和V。

指令示例:

ADCR2,R4

SBCR0,R1

MUR7,R6

(6)按位邏輯操作AND、ORR、EOR和BIC

指令格式:

opRd,Rm

其中:

op為AND、ORR、EOR或BIC。

Rd:目的寄存器,它也包含第一操作數,Rd必須在R0~R7范圍內。

Rm:第二操作數寄存器,Rm必須在R0~R7范圍內。

這些指令用于對Rd和Rm中的值進行按位邏輯操作,結果放在Rd中,操作如下:

AND:進行邏輯“與”操作。

ORR:進行邏輯“或”操作。

EOR:進行邏輯“異或”操作。

BIC:進行“RdANDNOTRm”操作。

這些指令根據結果更新標志N和Z。

程序示例:

ANDR1,R2

ORR R0,R1

EOR R5,R6

BIC R7,R6

(7)移位和循環移位操作ASR、S、SR和ROR

Thumb指令集中,移位和循環移位操作作為獨立的指令使用,這些指令可使用寄存器中的值或立即數移位量。

指令格式:

opRd,Rs

opRd,Rm,#expr

其中:

op是下列其中之一:

ASR:算術右移,將寄存器中的內容看做補碼形式的帶符號整數。將符號位復制到空出位。

S:邏輯左移,空出位填零。

SR:邏輯右移,空出位填零。

ROR:循環右移,將寄存器右端移出的位循環移回到左端。ROR僅能與寄存器控制的移位一起使用。

Rd:目的寄存器,它也是寄存器控制移位的源寄存器。Rd必須在R0~R7范圍內。

Rs:包含移位量的寄存器,Rs必須在R0~R7范圍內。

Rm:立即數移位的源寄存器,Rm必須在R0~R7范圍內。

expr:立即數移位量,它是一個取值(在匯編時)為整數的表達式。整數的范圍為:若op是S,則為0~31;其他情況則為1~32。

對于除ROR以外的所有指令:

若移位量為32,則Rd清零,最后移出的位保留在標志C中。

若移位量大于32,則Rd和標志C均被清零。

這些指令根據結果更新標志N和Z,且不影響標志V。對于標志C,若移位量是零,則不受影響。其他情況下,它包含源寄存器的最后移出位。

指令示例:

ASRR3,R5

SRR0,R2,#16??;將R2的內容邏輯右移16次后,結果放入R0中

SRR5,R5,av

(8)比較指令CMp和CMN

指令格式:

CMpRn,#expr

CMpRn,Rm

CMNRn,Rm

其中:

Rn:第一操作數寄存器。

expr:表達式,其值(在匯編時)為在0~255范圍內的整數。

Rm:第二操作數寄存器。

CMp指令從Rn的值中減去expr或Rm的值,CMN指令將Rm和Rn的值相加,這些指令根據結果更新標志N、Z、C和V,但不往寄存器中存放結果。

對于“CMpRn,#expr”和CMN指令,Rn和Rm必須在R0~R7范圍內。

對于“CMpRn,Rm”指令,Rn和Rm可以是R0~R15中的任何寄存器。

指令示例:

CMpR2,#255

CMpR7,R12

CMNR,R5

(9)傳送、傳送非和取負(MOV、MVN和NEG)

指令格式:

MOVRd,#expr

MOVRd,Rm

MVNRd,Rm

NEGRd,Rm

其中:

Rd:目的寄存器。

expr:表達式,其取值為在0~255范圍內的整數。

Rm:源寄存器。

MOV指令將#expr或Rm的值放入Rd。MVN指令從Rm中取值,然后對該值進行按位邏輯“非”操作,結果放入Rd。NEG指令取Rm的值再乘以-1,結果放入Rd。

對于“MOVRd,#expr”、MVN和NEG指令,Rd和Rm必須在R0~R7范圍內。

對于“MOVRd,Rm”指令,Rd和Rm可以是寄存器R0~R15中的任意一個。

“MOVRd,#expr”和MVN指令更新標志N和Z,對標志C或V無影響。NEG指令更新標志N、Z、C和V?!癕OVRd,Rm”指令中,若Rd或Rm是高寄存器(R8~R18),則標志不受影響;若Rd和Rm都是低寄存器(R0~R7),則更新標志N和Z,且清除標志C和V。

指令示例:

MOVR3,#0

MOVR0,R12

MVNR7,R1

NEGR2,R2

(10)測試位TST

指令格式:

TSTRn,Rm

其中:

Rn:第一操作數寄存器。

Rm:第二操作數寄存器。

TST對Rm和Rn中的值進行按位“與”操作。但不把結果放入寄存器。該指令根據結果更新標志N和Z,標志C和V不受影響。Rn和Rm必須在R0~R7范圍內。

指令示例:

TSTR2,R4

3.分支指令

(1)分支B指令

這是Thumb指令集中唯一的有條件指令。

指令格式:

B{cd}abe

其中,abe是程序相對偏移表達式,通常是在同一代碼塊內的標號。若使用cond,則abe必須在當前指令的-256~+256字節范圍內。若指令是無條件的,則abe必須在±2KB范圍內。若cond滿足或不使用cond,則B指令引起處理器轉移到abe。

abe必須在指定限制內。ARM鏈接器不能增加代碼來產生更長的轉移。

指令示例:

Bdoop

BEGsectB

(2)帶鏈接的長分支B指令

指令格式:

Babe

其中,1abe為程序相對轉移表達式。B指令將下一條指令的地址復制到R14(鏈接寄存器),并引起處理器轉移到1abe。

B指令不能轉移到當前指令±4MB以外的地址。必要時,ARM鏈接器插入代碼以允許更長的轉移。

指令示例:

Bextract

(3)分支,并可選地切換指令集BX

指令格式:

BX Rm

其中,Rm裝有分支目的地址的ARM寄存器。Rm的位[0]不用于地址部分。若Rm的位[0]清零,則位[1]也必須清零,指令清除CpSR中的標志T,目的地址的代碼被解釋為ARM代碼,BX指令引起處理器轉移到Rm存儲的地址。若Rm的位[0]置位,則指令集切換到Thumb狀態。

指令示例:

BX R5

(4)帶鏈接分支,并可選地交換指令集BX

指令格式:

BX Rm

BX abe

其中,Rm裝有分支目的地址的ARM寄存器。Rm的位[0]不用于地址部分。若Rm的位[0]清零,則位[1]必須也清零,指令清除CpSR中的標志T,目的地址的代碼被解釋為ARM代碼。abe為程序相對偏移表達式,“BXabe”始終引起處理器切換到ARM狀態。

BX指令可用于:

復制下一條指令的地址到R14。

引起處理器轉移到abe或Rm存儲的地址。

如果Rm的位[0]清零,或使用“BXabe”形式,則指令集切換到ARM狀態。

指令不能轉移到當前指令±4Mb范圍以外的地址。必要時,ARM鏈接器插入代碼以允許更長的轉移。

指令示例:

BX R6

BX armsub

4.中斷和斷點指令

(1)軟件中斷SWI指令

指令格式:

SWIimmed_8

其中,immed_8為數字表達式,其取值為0~255范圍內的整數。

SWI指令引起SWI異常。這意味著處理器狀態切換到ARM態;處理器模式切換到管理模式,CpSR保存到管理模式的SpSR中,執行轉移到SWI向量地址。處理器忽略immed_8,但immed_8出現在指令操作碼的位[7:0]中,而異常處理程序用它來確定正在請求何種服務,這條指令不影響條件碼標志。

指令示例:

SWI12

(2)斷點BKpT指令

指令格式:

BKpTimmed_8

其中,immed_8為數字表達式,取值為0~255范圍內的整數。

BKpT指令引起處理器進入調試模式。調試工具利用這一點來調查到達特定地址的指令時的系統狀態。盡管immed_8出現在指令操作碼的位[7:0]中,處理器忽略immed_8。調試器用它來保存有關斷點的附加信息。

指令示例:

BKpT67

Thumb指令特點

1、Thumb指令繼承了ARM指令集的許多特點

Thumb指令也是采用Load/Store結構,有數據處理、數據傳送及流控制指令等。

2、Thumb指令集丟棄了ARM指令集一些特性

大多數Thumb指令是無條件執行的(除了轉移指令B),而所有ARM指令都是條件執行的。許多Thumb數據處理指令采用2地址格式,即目的寄存器與一個源寄存器相同,而大多數ARM數據處理指令采用的是3地址格式(除了64位乘法指令外)。

3、Thumb異常時表現的一些特點

所有異常都會使微處理器返回到ARM模式狀態,并在ARM的編程模式中處理。由于ARM微處理器字傳送地址必須可被4整除(即字對準),半字傳送地址必須可被2整除(即半字對準)。而Thumb指令是2個字節長,而不是4個字節,所以,由Thumb執行狀態進入異常時其自然偏移與ARM不同。

Thumb狀態切換

1、在任何時刻,CpSR的第5位(位T)決定了ARM微處理器執行的是ARM指令流還是Thumb指令流。當T置1,則認為是16位的Thumb指令流;當T置0,則認為是32位的ARM指令流。

2、進入Thumb模式

3、進入Thumb指令模式有兩種方法:一種是執行一條交換轉移指令BX,另一種方法是利用異常返回,也可以把微處理器從ARM模式轉換為Thumb模式。

4、退出Thumb模式

退出Thumb指令模式也有兩種方法:一種是執行Thumb指令中的交換轉移BX指令可以顯式的返回到ARM指令流。另一種是利用異常進入ARM指令流。

Thumb數據處理指令

Thumb數據處理指令包括一組高度優化且相當復雜的指令,范圍涵蓋編譯器通常需要的大多數操作。ARM指令支持在單條指令中完成一個操作數的移位及一個ALU操作,但Thumb指令集將移位操作和ALU操作分離為不同的指令。本部分從以下幾個方面介紹:

數據處理指令的二進制編碼

數據處理指令的分類

ARM指令與Thumb指令比較

數據處理指令的二進制編碼如下圖:

按照數據處理指令的功能,可以將其分為以下幾類:

ADD與SUB—低寄存器加法和減法

ADD—高或低寄存器

ADD與SUB—Sp

ADD—pC或Sp相對偏移

ADC,SBC和MUL

ARM指令與Thumb指令低寄存器比較:

ARM指令與Thumb指令高寄存器比較:

關于Thumb指令,電子元器件資料就介紹完了,您有什么想法可以聯系小編。

  • 帶電接燈,很多電工都害怕觸電,其實按照這個順序,就不會觸電
  • 電工用的剝線鉗,剝電線皮太費勁,老電工有絕招,輕松搞定
  • 插座孔只能接2根線,遇到3根線怎么辦?老電工教你一招,輕松解決
  • 二極管區分正負極,老電工有絕招,不用任何儀表,肉眼一看就知道
  • 電工知識:時控開關上的T代表什么意思?火線接左邊還是右邊