Thumb指令

Thumb指令

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

指令分類

thumb指令集分為:分支指令、數據傳送指令、單暫存器載入和存儲指令以及多暫存器載入和存儲指令。thumb指令集沒有協處理器指令、信號量(semaphore)指令以及訪問cpsr或spsr的指令。

1.存儲器訪問指令

(1)dr和str--立即數偏移  載入暫存器和存儲暫存器。存儲器的地址以一個暫存器的立即數偏移(immediate offset)指明。

指令格式:

op rd, rn,#immed_5×4]

oph rd, rn,#immed_5×2]

opb rd, 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整除。

指令示例:

dr r3,5,#0]  strb r0,3,#31]  strh r7,3,#16]  drb r2,4,#1abe-{pc}

(2)dr和str--暫存器偏移  載入暫存器和存儲暫存器。用一個暫存器的基於暫存器偏移指明存儲器地址。  指令格式:

op rd,n,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整除。

指令示例:

dr r2,,r5]  drsh r0,0,r6]  strb r,7,r0]

(3)dr和str--pc或sp相對偏移  載入暫存器和存儲暫存器。用pc或sp中值的立即數偏移指明存儲器中的地址。沒有pc相對偏移的str指令。

指令格式:

dr rd,c,#immed_8×4]

dr rd,be

dr rd,sp,#immed_8×4]

str rd, p,#immed_8×4]

其中:

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

abe:程式相對偏移表達式。abe必須在當前指令之後且1kb範圍內。

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

dr:從存儲器中載入一個字。

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

指令示例:

dr r2,c,#1016] dr r5,ocadata  dr r0,p,#920]  str r,p,#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  載入和存儲多個暫存器。

指令格式:

op rn!,{regist}

其中:

op為dmia或stmia。

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

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

對於dmia指令,rn的最終值是載入的值,不是增加後的地址。

對於stmia指令,rn存儲的值有兩種情況:

若rn是暫存器列表中最低數字的暫存器,則rn存儲的值為rn的初值;其他情況則不可預知,當然,regist中最好不包括rn。

指令示例:  dmia r3!,{r0,r4}  dmia r5!,{r0~r7}  stmia r0!,{r6,r7}  stmia r3!,{r3,r5,r7}

2. 數據處理指令

(1)add和sub--低暫存器  加法和減法。對於低暫存器操作,這2條指令各有如下3種形式:

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

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

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

指令格式:

op rd,rn,rm

op rd,rn,#expr3

op rd,#expr8

其中:

op為add或sub。

rd:目的暫存器。它也用做“op rd,#expr8”的第1個運算元。

rn:第一運算元暫存器。

rm:第二運算元暫存器。

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

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

“op rd,rn,rm”執行rn+rm或rn-rm操作,結果放在rd中。

“op rd,rn,#expr3”執行rn+expr3或rn-expr3操作,結果放在rd中。

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

expr3或expr8為負值的add指令彙編成相對應的帶正數常量的sub指令。expr3或expr8為負值的sub指令彙編成相對應的帶正數常量的add指令。

rd、rn和rm必須是低暫存器(r0~r7)。

這些指令更新標誌n、z、c和v。

指令示例:  add r3,r,r5  sub r0,r4,#5  add r7,#201

(2)add--高或低暫存器  將暫存器中值相加,結果送回到第一運算元暫存器。

指令格式:

add rd,rm

其中:

rd:目的暫存器,也是第一運算元暫存器。

rm:第二運算元暫存器。

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

當rd和rm都是低暫存器時,指令“add rd,rm”彙編成指令“add rd,rd,rm”。若rd和rm是低暫存器,則更新條件碼標誌n、z、c 和v;其他情況下這些標誌不受影響。

指令示例:  add r12,r4

(3)add和sub--sp  sp加上或減去立即數常量。

指令格式:

add sp,#expr

sub sp,#expr

其中:

expr為表達式,取值(在彙編時)為在-508~+508範圍內的4的整倍數。

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

expr為負值的add指令彙編成相對應的帶正數常量的sub指令。expr為負值的sub指令彙編成相對應的帶正數常量的add指令。

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

指令示例:  add sp,#32  sub sp,#96

(4)add--pc或sp相對偏移  sp或pc值加一立即數常量,結果放入低暫存器。

指令格式:  add rd,rp,#expr

其中:

rd:目的暫存器。rd必須在r0~r7範圍內。

rp:sp 或pc。  expr:表達式,取值(彙編時)為在0~1020範圍內的4的整倍數。

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

若rp是pc,則使用值是(當前指令地址+4)and &ffffffc,即忽略地址的低2位。

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

指令示例:  add r6,sp,#64  add r2,pc,#980

(5)adc、sbc和mu  帶進位的加法、帶進位的減法和乘法。

指令格式:

op rd,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。

指令示例:  adc r2,r4  sbc r0,r1  mu r7,r6

(6)按位邏輯操作and、orr、eor和bic

指令格式:  op rd,rm

其中:

op為and、orr、eor或bic。

rd:目的暫存器,它也包含第一運算元,rd必須在r0~r7範圍內。

rm:第二運算元暫存器,rm 必須在r0~r7範圍內。

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

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

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

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

bic:進行“rd and not rm”操作。

這些指令根據結果更新標誌n和z。

程式示例:  and r1,r2  orr r0,r1  eor r5,r6  bic r7,r6

(7)移位和循環移位操作asr、s、sr和ror  thumb指令集中,移位和循環移位操作作為獨立的指令使用,這些指令可使用暫存器中的值或立即數移位量。

指令格式:

op rd,rs

op rd,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,若移位量是零,則不受影響。其他情況下,它包含源暫存器的最後移出位。

指令示例:  asr r3,r5  sr r0,r2,#16 ;將r2的內容邏輯右移16次後,結果放入r0中  sr r5,r5,av

(8)比較指令cmp 和cmn

指令格式:

cmp rn,#expr

cmp rn,rm

cmn rn,rm

其中:

rn:第一運算元暫存器。

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

rm:第二運算元暫存器。

cmp指令從rn的值中減去expr或rm的值,cmn指令將rm和rn的值相加,這些指令根據結果更新標誌n、z、c和v,但不往暫存器中存放結果。

對於“cmp rn,#expr”和cmn指令,rn和rm必須在r0~r7範圍內。

對於“cmp rn,rm”指令,rn和rm可以是r0~r15中的任何暫存器。

指令示例:  cmp r2,#255  cmp r7,r12  cmn r,r5

(9)傳送、傳送非和取負(mov、mvn和neg)

指令格式:

mov rd,#expr

mov rd,rm

mvn rd,rm

neg rd,rm

其中:

rd:目的暫存器。

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

rm:源暫存器。

mov指令將#expr或rm的值放入rd。mvn指令從rm中取值,然後對該值進行按位邏輯“非”操作,結果放入rd。neg指令取rm的值再乘以-1,結果放入rd。

對於“mov rd,#expr”、mvn和neg指令,rd和rm必須在r0~r7範圍內。

對於“mov rd,rm”指令,rd和rm可以是暫存器r0~r15中的任意一個。

“mov rd,#expr”和mvn 指令更新標誌n和z,對標誌c或v無影響。neg指令更新標誌n、z、c 和v。“mov rd,rm”指令中,若rd或rm是高暫存器(r8~r18),則標誌不受影響;若rd 和rm 都是低暫存器(r0~r7),則更新標誌n和z,且清除標誌c和v。

指令示例:  mov r3,#0  mov r0,r12  mvn r7,r1  neg r2,r2

(10)測試位tst

指令格式:

tst rn,rm

其中:

rn:第一運算元暫存器。

rm:第二運算元暫存器。

tst對rm和rn中的值進行按位“與”操作。但不把結果放入暫存器。該指令根據結果更新標誌n和z,標誌c和v不受影響。rn和rm必須在r0~r7範圍內。

指令示例:  tst r2,r4

3. 分支指令

(1)分支b指令  這是thumb指令集中唯一的有條件指令。

指令格式:

b{cond} abe

其中:

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

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

指令示例:  b doop  beg sectb

(2)帶連結的長分支b指令

指令格式:

b abe

其中,1abe為程式相對轉移表達式。b指令將下一條指令的地址複製到r14(連結暫存器),並引起處理器轉移到1abe。

b指令不能轉移到當前指令±4mb以外的地址。必要時,arm連結器插入代碼以允許更長的轉移。

指令示例:  b extract

(3)分支,並可選地切換指令集bx

指令格式:

bx  rm

其中:

rm裝有分支目的地址的arm暫存器。rm的位]不用於地址部分。若rm 的位]清零,則位]也必須清零,指令清除cpsr中的標誌t,目的地址的代碼被解釋為arm代碼,bx指令引起處理器轉移到rm存儲的地址。若rm的位]置位,則指令集切換到thumb狀態。

指令示例:  bx  r5

(4)帶連結分支,並可選地交換指令集bx  指令格式:  bx  rm  bx  abe  其中,rm 裝有分支目的地址的arm暫存器。rm的位]不用於地址部分。若rm 的位]清零,則位]必須也清零,指令清除cpsr中的標誌t,目的地址的代碼被解釋為arm代碼。abe為程式相對偏移表達式,“bx abe”始終引起處理器切換到arm狀態。  bx指令可用於:  複製下一條指令的地址到r14。  引起處理器轉移到abe或rm存儲的地址。  如果rm的位]清零,或使用“bx abe”形式,則指令集切換到arm狀態。  指令不能轉移到當前指令±4mb範圍以外的地址。必要時,arm連結器插入代碼以允許更長的轉移。  指令示例:  bx  r6  bx  armsub

4. 中斷和斷點指令

(1)軟體中斷swi指令

指令格式:

swi immed_8

其中,immed_8為數字表達式,其取值為0~255範圍內的整數。  swi指令引起swi異常。這意味著處理器狀態切換到arm態;處理器模式切換到管理模式,cpsr保存到管理模式的spsr中,執行轉移到swi向量地址。處理器忽略immed_8,但immed_8出現在指令操作碼的位:0]中,而異常處理程式用它來確定正在請求何種服務,這條指令不影響條件碼標誌。

指令示例:  swi 12

(2)斷點bkpt指令

指令格式:

bkpt immed_8

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

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

指令示例:  bkpt 67

指令特點

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不同。

狀態切換

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數據處理指令包括一組高度最佳化且相當複雜的指令,範圍涵蓋編譯器通常需要的大多數操作。arm指令支持在單條指令中完成一個運算元的移位及一個alu操作,但thumb指令集將移位操作和alu操作分離為不同的指令。本部分從以下幾個方面介紹:  數據處理指令的二進制編碼  數據處理指令的分類  arm指令與thumb指令比較  數據處理指令的二進制編碼如下圖:
按照數據處理指令的功能,可以將其分為以下幾類:

add與sub—低暫存器加法和減法

add—高或低暫存器

add與sub—sp

add—pc或sp相對偏移

adc,sbc和mul

arm指令與thumb指令低暫存器比較:
arm指令與thumb指令高暫存器比較:

相關詞條

相關搜尋

熱門詞條

聯絡我們