<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          ARM Thumb Thumb-2指令集

          作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
          32位RISC芯片ARM 體系結(jié)構(gòu)支持兩種指令集:32位的ARM指令集執(zhí)行效率高,對ARM體系架構(gòu)所有功能的完整支持;16位的Thumb指令集是ARM指令集的子集并以良好的代碼密度著稱。如果拋開預(yù)取指令時(shí)間不計(jì),ARM指令相對Thumb指令將有更好的運(yùn)行性能(預(yù)取指令時(shí)需要根據(jù)指令地址偏移量來取指, ARM支持更大的地址偏移量而比較耗時(shí))。最近ARM公司推出的的Thumb-2/Thumb2指令集據(jù)稱是上述兩種特性的綜合,是ARM指令集的性能和Thumb指令集的代碼密度的折中。號(hào)稱達(dá)到98%的ARM性能而又能降低代碼密度達(dá)30%。在目前的大多數(shù)ARM應(yīng)用中依然采用ARM + Thumb代碼的混雜模式。ARM code對應(yīng)的CPU(ARM處理器)工作狀態(tài)稱為ARM State,Thumb對應(yīng)的稱之為Thumb State,這兩種狀態(tài)的不同主要通過CPSR[bit 5]區(qū)別。CPSR(當(dāng)前程序狀態(tài)寄存器)保存了處理器的當(dāng)前工作狀態(tài),[bit 5]也被稱為T bit。對于所有帶有J標(biāo)志的處理器核,比如ARM926EJ-S和ARM1136J-S,J(Jazelle)代表ARM核中集成了Jazelle技 術(shù)。CPSR[bit24]則被成為J bit,如果這位為1,則代表當(dāng)前CPU工作在Java State下而CPU的取指和解碼都是直接操作Java操作數(shù)棧。當(dāng)然要生成Jazelle支持的字節(jié)碼需要特殊的Java編譯器和JVM,一般由第三方 平臺(tái)軟件廠商提供,比如日本的Aplix公司。在ARM處理器的運(yùn)行過程中,匯編指令BX以及BLX可以完成ARM State和Thumb State之間的切換(BXJ和BLXJ完成ARM/Thumb State和Java State之間的切換)。但如果程序有一部分工作在ARM工作狀態(tài)下,一部分工作在Thumb工作狀態(tài)下,而這兩段代碼卻有交互調(diào)用,則在編譯C/C++和匯編源文件時(shí)要 加上 -apcs /interwork選項(xiàng)。ARM公司的ADS(ARM Developer Suite,-apcs /interwork)和RealView的RVDS(RealView Developer Suite,--apcs /interwork) 都支持這樣的編譯選項(xiàng),他們會(huì)在鏈接時(shí)自動(dòng)檢測函數(shù)之間的調(diào)用關(guān)系和工作狀態(tài)提供粘合劑(Veneers)以便程序能夠在不同的工作狀態(tài)下切換。arm-linux-gcc編譯器個(gè)別版本不支持這個(gè)選項(xiàng),所以在開發(fā)ARM + Linux平臺(tái)下使用的程序時(shí)應(yīng)該注意到這個(gè)問題。最后比較了arm-linux-gcc編譯器下ARM(armv7-a)、Thumb-1、Thumb-2指令集以及armv5te、Cortex-A9與Cortex-A8的tune選項(xiàng)效率性能和代碼密度。

          本文引用地址:http://www.ex-cimer.com/article/201611/317419.htm

          圖1. ARM體系結(jié)構(gòu)演進(jìn)圖

          ARM指令集(A32)

          ARM指令集為32位指令集,指令地址必須對齊在4字節(jié)邊界,可以實(shí)現(xiàn)ARM架構(gòu)下所有功能。大多數(shù)ARM數(shù)據(jù)處理指令采用的是3地址格式(除了64位乘法指令外),即兩個(gè)源操作數(shù)和一個(gè)結(jié)果操作數(shù)。

          控制比特含義

          代號(hào)

          N(Negative)

          當(dāng)為負(fù)數(shù)時(shí),設(shè)為1

          Z(Zero)

          當(dāng)為0時(shí)設(shè)為1

          C(Carry)

          當(dāng)結(jié)果帶進(jìn)位時(shí)設(shè)為1

          V(Overflow)

          當(dāng)結(jié)果溢出時(shí)設(shè)為1

          ARM指令分為以下幾種:

          一、ARM 存儲(chǔ)器訪問指令
          助記符 說明 操作 條件碼位置
          LDR Rd,addressing 加載字?jǐn)?shù)據(jù) Rd←[addressing],addressing 索引 LDR{cond}
          LDRB Rd,addressing 加載無符字節(jié)數(shù)據(jù) Rd←[addressing],addressing 索引 LDR{cond}B
          LDRT Rd,addressing 以用戶模式加載字?jǐn)?shù)據(jù) Rd←[addressing],addressing 索引 LDR{cond}T
          LDRBT Rd,addressing 以用戶模式加載無符號(hào)字?jǐn)?shù)據(jù) Rd←[addressing],addressing 索引 LDR{cond}BT
          LDRH Rd,addressing 加載無符半字?jǐn)?shù)據(jù) Rd←[addressing],addressing 索引 LDR{cond}H
          LDRSB Rd,addressing 加載有符字節(jié)數(shù)據(jù) Rd←[addressing],addressing 索引 LDR{cond}SB
          LDRSH Rd,addressing 加載有符半字?jǐn)?shù)據(jù) Rd←[addressing],addressing 索引 LDR{cond}SH
          STR Rd,addressing 存儲(chǔ)字?jǐn)?shù)據(jù) [addressing]←Rd,addressing 索引 STR{cond}
          STRB Rd,addressing 存儲(chǔ)字節(jié)數(shù)據(jù) [addressing]←Rd,addressing 索引 STR{cond}B
          STRT Rd,addressing 以用戶模式存儲(chǔ)字?jǐn)?shù)據(jù) [addressing]←Rd,addressing 索引 STR{cond}T
          SRTBT Rd,addressing 以用戶模式存儲(chǔ)字節(jié)數(shù)據(jù) [addressing]←Rd,addressing 索引 STR{cond}BT
          STRH Rd,addressing 存儲(chǔ)半字?jǐn)?shù)據(jù) [addressing]←Rd,addressing 索引 STR{cond}H
          LDM{mode} Rn{!},reglist 批量(寄存器)加載 reglist←[Rn…],Rn 回存等 LDM{cond}{more}
          STM{mode} Rn{!},rtglist 批量(寄存器)存儲(chǔ) [Rn…]← reglist,Rn 回存等 STM{cond}{more}
          SWP Rd,Rm,Rn 寄存器和存儲(chǔ)器字?jǐn)?shù)據(jù)交換 Rd←[Rd],[Rn]←[Rm](Rn≠Rd 或 Rm) SWP{cond}
          SWPB Rd,Rm,Rn 寄存器和存儲(chǔ)器字節(jié)數(shù)據(jù)交換 Rd←[Rd],[Rn]←[Rm](Rn≠Rd 或 Rm) SWP{cond}B

          二、ARM 數(shù)據(jù)處理指令
          助記符號(hào) 說明 操作 條件碼位置
          MOV Rd ,operand2 數(shù)據(jù)轉(zhuǎn)送 Rd←operand2 MOV {cond}{S}
          MVN Rd ,operand2 數(shù)據(jù)非轉(zhuǎn)送 Rd←(operand2) MVN {cond}{S}
          ADD Rd,Rn operand2 加法運(yùn)算指令 Rd←Rn+operand2 ADD {cond}{S}
          SUB Rd,Rn operand2 減法運(yùn)算指令 Rd←Rn-operand2 SUB {cond}{S}
          RSB Rd,Rn operand2 逆向減法指令 Rd←operand2-Rn RSB {cond}{S}
          ADC Rd,Rn operand2 帶進(jìn)位加法 Rd←Rn+operand2+carry ADC {cond}{S}
          SBC Rd,Rn operand2 帶進(jìn)位減法指令 Rd←Rn-operand2-(NOT)Carry SBC {cond}{S}
          RSC Rd,Rn operand2 帶進(jìn)位逆向減法指令 Rd←operand2-Rn-(NOT)Carry RSC {cond}{S}
          AND Rd,Rn operand2 邏輯與操作指令 Rd←Rn&operand2 AND {cond}{S}
          ORR Rd,Rn operand2 邏輯或操作指令 Rd←Rn|operand2 ORR {cond}{S}
          EOR Rd,Rn operand2 邏輯異或操作指令 Rd←Rn^operand2 EOR {cond}{S}
          BIC Rd,Rn operand2 位清除指令 Rd←Rn&(~operand2) BIC {cond}{S}
          CMP Rn,operand2 比較指令 標(biāo)志 N、Z、C、V←Rn-operand2 CMP {cond}
          CMN Rn,operand2 負(fù)數(shù)比較指令 標(biāo)志 N、Z、C、V←Rn+operand2 CMN {cond}
          TST Rn,operand2 位測試指令 標(biāo)志 N、Z、C、V←Rn&operand2 TST {cond}
          TEQ Rn,operand2 相等測試指令 標(biāo)志 N、Z、C、V←Rn^operand2 TEQ {cond}

          三、乘法指令
          具有 32×32 乘法指令,32×32 乘加指令,32×32 結(jié)果為 64 位的乘/乘法指令.
          助記符 說明 操作 條件碼位置
          MUL Rd,Rm,Rs 32 位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
          MLA Rd,Rm,Rs,Rn 32 位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
          UMULL RdLo,RdHi,Rm,Rs 64 位無符號(hào)乘法指令 (RdLo,RdHi)←Rm*Rs UMULL{cond}{S}
          UMLAL RdLo,RdHi,Rm,Rs 64 位無符號(hào)乘加指令 (RdLo,RdHi)←Rm*Rs+(RdLo,RdHi) UMLAL{cond}{S}
          SMULL RdLo,RdHi,Rm,Rs 64 位有符號(hào)乘法指令 (RdLo,RdHi)←Rm*Rs SMULL{cond}{S}
          SMLAL RdLo,RdHi,Rm,Rs 64 位有符號(hào)乘加指令 (RdLo,RdHi)←Rm*Rs+(RdLo,RdHi) SMLAL{cond}{S}

          四、跳轉(zhuǎn)指令
          在 ARM 中有兩種方式可以實(shí)現(xiàn)程序的跳轉(zhuǎn),一種是使用跳轉(zhuǎn)指令直接跳轉(zhuǎn),另一種則是直接向 PC 寄存器賦值實(shí)現(xiàn)跳轉(zhuǎn).

          助記符 說明 操作 條件碼位置
          B label 跳轉(zhuǎn)指令 Pc←label B{cond}
          BL label 帶鏈接的跳轉(zhuǎn)指令 LR←PC-4, PC←label BL{cond}
          BX Rm 帶狀態(tài)切換的跳轉(zhuǎn)指令 PC←label,切換處理狀態(tài) BX{cond}

          五、ARM協(xié)處理器指令
          ARM 支持協(xié)處理器操作,協(xié)處理器的控制要通過協(xié)處理器命令實(shí)現(xiàn).
          助記符 說明 操作 條件碼位置
          CDP
          coproc,opcodel,CRd,CRn,CRm{,opcode2} 協(xié)處理器數(shù)據(jù)操作指令 取決于協(xié)處理器 CDP{cond}
          LDC{L} coproc,CRd〈地址〉 協(xié)處理器數(shù)據(jù)讀取指令 取決于協(xié)處理器 LDC{cond}{L}
          STC{L} coproc,CRd,〈地址〉 協(xié)處理器數(shù)據(jù)寫入指令 取決于協(xié)處理器 STC{cond}{L}
          ARM 寄存器到協(xié)處理器
          MCR coproc, opcodel,Rd,CRn,{,opcode2} 寄存器的數(shù)據(jù)傳送指令 取決于協(xié)處理器 MCR{cond}
          協(xié)處理器寄存器到 ARM
          MRC coproc, opcodel,Rd,CRn,{,opcode2} 寄存器到數(shù)據(jù)傳送指令 取決于協(xié)處理器MCR{cond}

          五、ARM 雜項(xiàng)指令
          助記符 說明 操作 條件碼位置
          SWI immed_24 軟中斷指令 產(chǎn)生軟中斷,處理器進(jìn)入管理模式 SWI{cond}
          MRS Rd,psr 讀狀態(tài)寄存器指令 Rd←psr,psr 為 CPSR 或 SPSR MRS{cond}
          MSR psr_fields,Rd/#immed_8r 寫狀態(tài)寄存器指令 psr_fields←Rd/#immed_8r,psr 為 CPSR 或 SPSR MSR{cond}

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

          Thumb指令集

          對于ARM指令來說,所有的指令長度都是32位,并且執(zhí)行周期大多為單周期,指令都是有條件執(zhí)行的。每條Thumb指令有相同處理器模型所對應(yīng)的32位ARM指令。而THUMB 指令的特點(diǎn)如下:

          • 不會(huì)經(jīng)常條件執(zhí)行使用指令:除了跳轉(zhuǎn)指令 B 有條件執(zhí)行功能外,其它指令均為無條件執(zhí)行
          • 源寄存器與目標(biāo)寄存器經(jīng)常是相同的以減少操作數(shù)
          • 可用寄存器數(shù)量少
          • 常數(shù)的值比較小
          • 不經(jīng)常用內(nèi)核中的桶式移位器(barrel shifter)

          Thumb指令集是對32位ARM指令集的擴(kuò)充,它的目標(biāo)是為了實(shí)現(xiàn)更高的代碼密度。Thumb指令集實(shí)現(xiàn)的功能只是32位ARM指令集的子集,它僅僅把常用的ARM指令壓縮成16位的指令編碼方式。在指令的執(zhí)行階段,16位的指令被重新解碼,完成對等的32位指令所實(shí)現(xiàn)的功能。與全部用ARM指令集的方式相比,使用Thumb指令可以在代碼密度方面改善大約30%。但是,這種改進(jìn)是以代碼的效率為代價(jià)的。盡管每個(gè)Thumb指令都有相對應(yīng)的ARM指令,但是,相同的功能需要更多的Thumb指令才能完成。因此,當(dāng)指令預(yù)取需要的時(shí)間沒有區(qū)別時(shí),ARM指令相對Thumb指令具有更好的性能。與ARM指令集相比較,Thumb指令集中的數(shù)據(jù)處理指令的操作數(shù)仍然是32位,指令地址也為32位,但Thumb指令集為實(shí)現(xiàn)16位的指令長度,舍棄了ARM指令集的一些特性,若使用32位的存儲(chǔ)器,ARM代碼比Thumb代碼快約40%,若使用16位的存儲(chǔ)器,Thumb代碼比ARM代碼快約40%~50%.顯然,ARM指令集和Thumb指令集各有其優(yōu)點(diǎn),若對系統(tǒng)的性能有較高要求,應(yīng)使用32位的存儲(chǔ)系統(tǒng)和ARM指令集,若對系統(tǒng)的成本及功耗有較高要求,則應(yīng)使用16位的存儲(chǔ)系統(tǒng)和Thumb指令集。當(dāng)然,若兩者結(jié)合使用,充分發(fā)揮其各自的優(yōu)點(diǎn),會(huì)取得更好的效果。

          在編寫Thumb指令時(shí),先要使用偽指令CODE16聲明,編寫ARM指令時(shí),則可使用CODE32偽指令聲明。Thumb 指令集沒有協(xié)處理器指令,信號(hào)量指令以及訪問 CPSR 或 SPSR 的指令,沒有乘加指令及 64 位乘法指令等,且指令的第二操作數(shù)受到限制;大多數(shù) Thumb 數(shù)據(jù)處理指令采用2地址格式.Thumb指令集與 ARM 指令的區(qū)別一般有如下幾點(diǎn):
          跳轉(zhuǎn)指令
          程序相對轉(zhuǎn)移,特別是條件跳轉(zhuǎn)與 ARM 代碼下的跳轉(zhuǎn)相比,在范圍上有更多的限制,轉(zhuǎn)向子程序是無條件的轉(zhuǎn)移.
          數(shù)據(jù)處理指令
          數(shù)據(jù)處理指令是對通用寄存器進(jìn)行操作,在大多數(shù)情況下,操作的結(jié)果須放入其中一個(gè)操作數(shù)寄存器中,而不是第 3 個(gè)寄存器中.數(shù)據(jù)處理操作比 ARM 狀態(tài)的更少,訪問寄存器 R8~R15 受到一定限制.除 MOV 和 ADD 指令訪問器 R8~R15 外,其它數(shù)據(jù)處理指令總是更新 CPSR 中的 ALU 狀態(tài)標(biāo)志.訪問寄存器 R8~R15 的 Thumb 數(shù)據(jù)處理指令不能更新 CPSR 中的 ALU 狀態(tài)標(biāo)志.
          單寄存器加載和存儲(chǔ)指令
          在 Thumb 狀態(tài)下,單寄存器加載和存儲(chǔ)指令只能訪問寄存器 R0~R7
          批量寄存器加載和存儲(chǔ)指令
          LDM 和 STM 指令可以將任何范圍為 R0~R7 的寄存器子集加載或存儲(chǔ). PUSH 和 POP 指令使用堆棧指令 R13 作為基址實(shí)現(xiàn)滿遞減堆棧.除 R0~R7 外,PUSH 指令還可以存儲(chǔ)鏈接寄存器 R14,并且 POP 指令可以加載程序指令PC

          Thumb-2指令集(T32)

          THUMB-2指令集是介紹ARM CPU中的THUMB的擴(kuò)展,新指令對性能和代碼密度的改進(jìn),從而提供低功耗,高性能的最優(yōu)設(shè)計(jì),更好的平衡代碼性能和系統(tǒng)成本,Thumb-2是混合的16-bit和32-bit指令格式,其16位指令在運(yùn)行時(shí)被轉(zhuǎn)換為32-bit指令執(zhí)行。Thumb-2指令集在Thumb指令的基礎(chǔ)上做了如下的擴(kuò)充:增加了一些新的16位Thumb指令來改進(jìn)程序的執(zhí)行流程,增加了一些新的32位Thumb指令以實(shí)現(xiàn)一些ARM指令的專有功能32位的ARM 指令也得到了擴(kuò)充,增加了一些新的指令來改善代碼性能和數(shù)據(jù)處理的效率給Thumb指令集增加32位指令就解決了之前Thumb指令集不能訪問協(xié)處理器、特權(quán)指令和特殊功能指令的局限。新的Thumb指令集現(xiàn)在可以實(shí)現(xiàn)所有的功能,這樣就不需要在ARM/Thumb狀態(tài)之間反復(fù)切換了,代碼密度和性能得到顯著的提高。Thumb-2的出現(xiàn)使開發(fā)者只使用一套指令集就享有高性能、高代碼密度,不再需要在不同指令之間反復(fù)切換了。開發(fā)者只需要關(guān)注對整體性能影響最大的那部分代碼,其他的部分可以使用缺省的編譯配置就可以了。

          新的Thumb-2技術(shù)可以帶來很多好處:
            可以實(shí)現(xiàn)ARM指令的所有功能
            增加了12條新指令,可以改進(jìn)代碼性能和代碼密度之間的平衡
            代碼性能達(dá)到了純ARM代碼性能的98%
            相對ARM代碼,Thumb-2代碼的大小僅有其74%
            代碼密度比現(xiàn)有的Thumb指令集更高:代碼大小平均降低5%;代碼速度平均提高2-3%

          為了提高處理壓縮數(shù)據(jù)結(jié)構(gòu)的效率,新的ARM架構(gòu)為Thumb-2指令集和ARM指令集增加了一些新的指令來實(shí)現(xiàn)比特位的插入和抽取。為了增加處理常數(shù)的靈活性,新架構(gòu)中為Thumb-2指令集和ARM指令集增加了兩條新的指令。MOVW可以把一個(gè)16-bit常數(shù)加載到寄存器中,并用0填充高比特位;另一條指令MOVT可以把一個(gè)16-bit常數(shù)加載到寄存器高16比特中。這兩條指令組合使用就可以把一個(gè)32-bit常數(shù)加載到寄存器中。通常在訪問外設(shè)寄存器之前會(huì)把外設(shè)的基址加載到寄存器中,這時(shí)就會(huì)需要把32-bit常數(shù)加載到寄存器中。在之前的架構(gòu)中需要通過literal pools來完成這樣的操作,對32位常量的訪問一般通過PC相對尋址來實(shí)現(xiàn)。Literal pools可以保存常量并簡化訪問這些常量的代碼,但是,在Harvard架構(gòu)的處理器中會(huì)引起額外的開銷。這些開銷來自于需要額外的時(shí)鐘周期來使數(shù)據(jù)端 口能夠?qū)χ噶盍鬟M(jìn)行訪問;這種訪問可能是需要把指令流加載的數(shù)據(jù)緩存中,或者從數(shù)據(jù)端口直接訪問指令存儲(chǔ)器。將32位常量分成16比特的兩個(gè)部分保存在兩條指令中,意味著數(shù)據(jù)直接在指令流中,不再需要通過數(shù)據(jù)端口來訪問了。相對于literal pool方式,這種解決辦法可以消除通過數(shù)據(jù)端口訪問指令流的額外開銷,進(jìn)而提高性能,降低功耗。

          ARM/Thumb狀態(tài)切換

          在基于ARM 處理器的嵌入式開發(fā)中,為了增強(qiáng)系統(tǒng)的靈活性以及提高系統(tǒng)的整體性能經(jīng)常需要使用16 位的Thumb 指令,所以需要在ARM 和Thumb 狀態(tài)之間來切換(Interworking)微處理器狀態(tài)。只要遵循ATPCS調(diào)用規(guī)則,Thumb子程序和ARM子程序就可以互相調(diào)用。首先介紹切換(Interwoking)的基本概念及切換時(shí)的子函數(shù)調(diào)用。

          ARM處理器總是從ARM狀態(tài)開始執(zhí)行。因而,如果要在調(diào)試器中運(yùn)行Thumb程序,必須為該Thumb程序添加一個(gè)ARM程序頭,然后再切換到Thumb狀態(tài),調(diào)用該Thumb程序。

          • Thumb狀態(tài) BX Rn
          • ARM狀態(tài) BX Rn

          其中Rn可以是寄存器R0—R15中的任意一個(gè)。指令可以通過將寄存器Rn的內(nèi)容拷貝到程序計(jì)數(shù)器PC來完成在4Gbyte地址空間中的絕對跳轉(zhuǎn),而狀態(tài)切換是由寄存器Rn的最低位來指定的,如果操作數(shù)寄存器的狀態(tài)位Bit0=0,則進(jìn)入ARM狀態(tài),如果Bit0=1,則進(jìn)入Thumb狀態(tài)。在非Interworking函數(shù)調(diào)用中,調(diào)用函數(shù)使用BL(Branch with Link)指令,即將返回地址保存在連接寄存器LR中,同時(shí)跳轉(zhuǎn)到被調(diào)用的子函數(shù)程序入口。從子函數(shù)返回時(shí)執(zhí)行指令 MOV PC, LR(當(dāng)然也可能是其他形式的指令,如出棧指令)將LR值直接放入PC中,從而返回到調(diào)用函數(shù)中的下一條指令的地址,然后繼續(xù)執(zhí)行程序。在Interworking函數(shù)的調(diào)用中,需要在編譯時(shí)對此函數(shù)所在的源程序指定編譯開關(guān)選項(xiàng):-apcs / interwork ,即保證程序遵守ARM/Thumb程序混合使用的ATPCS規(guī)則。一般來說,這時(shí)生成的目標(biāo)代碼會(huì)增加2%左右。這樣在編譯器(compiler)處理這個(gè)函數(shù)時(shí)就會(huì)用BX 指令取代MOV PC,LR指令,而且連接器(linker)會(huì)自動(dòng)的產(chǎn)生一小段代碼(veneers)來改變處理器狀態(tài)(ARM/Thumb),對于C/C++程序來說,當(dāng)編譯時(shí)如果增加 –apcs/interwork 選項(xiàng),那就是告訴連接器自動(dòng)增加一小段代碼(veneer)來實(shí)現(xiàn)函數(shù)調(diào)用時(shí)ARM/Thumb的狀態(tài)切換。但是對于使用C程序中的Interwork選項(xiàng),需要注意的是:

          • 對于一個(gè)C /C++源程序中不能同時(shí)包含ARM/Thumb指令;
          • 如果C/C++程序間接的調(diào)用另一種指令系統(tǒng)下的子程序,編譯該程序時(shí)需要增加-apcs/interwork選項(xiàng);
            • 編譯用于交互工作的ARM C代碼: armcc -apcs/interwork
            • 編譯用于交互工作的Thumb C代碼:tcc -apcs/interwork
          • 如果調(diào)用程序和被調(diào)用程序是不同的指令,而被調(diào)用程序是Non-Interworking代碼,這時(shí)不要使用函數(shù)指針來調(diào)用該被調(diào)用程序。

          對于匯編程序來說,如果本代碼是被調(diào)用的函數(shù),則需按照以下步驟處理:

          • 編譯時(shí)增加-apcs/interwork 選項(xiàng);ARM匯編armasm -32 -apcs /interwork;Thumb匯編代碼:armasm -16 -apcs /interwork;
          • 在入口處保護(hù)返回地址(lr)以及寄存器(r0-r7,r8-r12(ARM))
          • 返回前恢復(fù)保護(hù)的寄存器
          • 用BX來返回;
          • EXPORT本函數(shù)名;

          如果本代碼是調(diào)用函數(shù),那就只需要用BL指令來實(shí)現(xiàn)子函數(shù)的調(diào)用即可,也就是正常的處理。當(dāng)然,用戶也可以自己來編寫這些狀態(tài)切換程序,這樣執(zhí)行代碼的效率會(huì)更高些。對于C/C++程序和匯編程序的相互調(diào)用同樣需要遵守以上的規(guī)則。另外,在實(shí)際應(yīng)用中,如果要在ARM/Thumb狀態(tài)間來切換程序,最好的辦法是所有的函數(shù)在編譯時(shí)都增加 -apcs/interwork選項(xiàng)。關(guān)于匯編代碼,也可在程序中使用CODE32或CODE16命令明確告知匯編程序下面的代碼是ARM代碼還是Thumb代碼,這樣在匯編時(shí)則無需使用-32、-16選項(xiàng);當(dāng)然也可在單個(gè)匯編原文件中混合使用ARM以及Thumb代碼,這是需要使用CODE32以及CODE16命令,并且需要注意狀態(tài)的切換,使用BX Rn,根據(jù)Rn的Bit[0]來確定目標(biāo)是ARM代碼還是Thumb代碼。如AREA Init,CODE,READONLY CODE32;通知編譯器其后的指令為32位的ARM指令。

          前面所提到的內(nèi)容是針對ARM微處理器內(nèi)核為V4T架構(gòu)時(shí)的切換情況,而對于V5TE架構(gòu)的ARM內(nèi)核,除了完全支持V4T架構(gòu)的代碼(具有veneers)外,代碼在連接時(shí)不再增加veneers,而是使用新的指令BLX(Branch and Link with Exchang)來實(shí)現(xiàn)狀態(tài)切換。這條指令完成完成的任務(wù)是:在跳轉(zhuǎn)時(shí)將返回的指令地址保存在LR寄存器中,同時(shí)將PC中的最低位的值拷貝到CPSR寄存器中的T位,從而改變處理器狀態(tài)(Exchange)。一般來說,對于調(diào)用函數(shù)使用BLX指令即可,被調(diào)用函數(shù)則與V4T架構(gòu)相同,也是使用BX指令來返回。
          ARM/Thumb代碼性能比較

          前面提到Thumb代碼所需的存儲(chǔ)空間約為ARM代碼的60%~70%;Thumb代碼使用的指令數(shù)比ARM代碼少約30%~40%;若使用32位的存儲(chǔ)器,ARM代碼比Thumb代碼速約40%;若使用16位的存儲(chǔ)器,Thumb代碼比ARM代碼速約40%~50%;與ARM代碼相比,使用Thumb代碼,存儲(chǔ)器的過耗會(huì)下降約30%。下面是arm-linux-gcc編譯器采用不同的編譯選擇對armv7-a,、thumb-2 和thumb-1指令集編譯CoreMark的測試結(jié)果,結(jié)果如下:

          • 最好的編譯選項(xiàng):-O3 -funroll-loops -marm -march=armv5te -mtune=cortex-a8
          • armv7-a指令集最好的編譯選項(xiàng):-O3 -funroll-loops -marm -march=armv7-a -mtune=cortex-a8 95.2%
          • Thumb-2指令集最好的編譯選項(xiàng):-O3 -funroll-loops -mthumb -march=armv7-a -mtune=cortex-a888.7%
          • Thumb-1指令集最好的編譯選項(xiàng):-O2 -mthumb -march=armv5te -mtune=cortex-a8 66.4%
          • Cortex-A9是Cortex-A8的tune的99.5%
          • 默認(rèn)選項(xiàng)-O2 -mthumb -march=armv7-a 性能比為80.8%

          Top of Form

          Score

          Optimisation

          Unroll?

          ISA

          Arch

          Tune

          % of best

          5634.6

          -O3

          -funroll-loops

          -marm

          -march=armv5te

          -mtune=cortex-a8

          100.0%

          5607.7

          -O3

          -funroll-loops

          -marm

          -march=armv5te

          -mtune=cortex-a9

          99.5%

          5601.5

          -O2

          -funroll-loops

          -marm

          -march=armv5te

          -mtune=cortex-a9

          99.4%

          5580.0

          -O3

          -marm

          -march=armv5te

          -mtune=cortex-a8

          99.0%

          5548.6

          -O3

          -marm

          -march=armv5te

          -mtune=cortex-a9

          98.5%

          5505.1

          -O2

          -marm

          -march=armv5te

          -mtune=cortex-a8

          97.7%

          5427.4

          -O2

          -funroll-loops

          -marm

          -march=armv5te

          -mtune=cortex-a8

          96.3%

          5386.5

          -O3

          -funroll-loops

          -marm

          -march=armv7-a

          -mtune=cortex-a9

          95.6%

          5364.4

          -O3

          -funroll-loops

          -marm

          -march=armv7-a

          -mtune=cortex-a8

          95.2%

          5332.3

          -O2

          -marm

          -march=armv5te

          -mtune=cortex-a9

          94.6%

          5330.8

          -O3

          -marm

          -march=armv7-a

          -mtune=cortex-a8

          94.6%

          5283.7

          -O3

          -marm

          -march=armv7-a

          -mtune=cortex-a9

          93.8%

          5253.5

          -O2

          -funroll-loops

          -marm

          -march=armv7-a

          -mtune=cortex-a9

          93.2%

          5066.5

          -O2

          -funroll-loops

          -marm

          -march=armv7-a

          -mtune=cortex-a8

          89.9%

          4996.6

          -O3

          -funroll-loops

          -mthumb

          -march=armv7-a

          -mtune=cortex-a8

          88.7%

          4995.6

          -O3

          -funroll-loops

          -mthumb

          -march=armv7-a

          -mtune=cortex-a9

          88.7%

          4947.2

          -O3

          -mthumb

          -march=armv7-a

          -mtune=cortex-a8

          87.8%

          4858.3

          -O2

          -funroll-loops

          -mthumb

          -march=armv7-a

          -mtune=cortex-a9

          86.2%

          4774.8

          -O2

          -funroll-loops

          -mthumb

          -march=armv7-a

          -mtune=cortex-a8

          84.7%

          4763.8

          -O2

          -marm

          -march=armv7-a

          -mtune=cortex-a9

          84.5%

          4737.8

          -Os

          -marm

          -march=armv5te

          -mtune=cortex-a8

          84.1%

          4731.1

          -O2

          -marm

          -march=armv7-a

          -mtune=cortex-a8

          84.0%

          4688.6

          -O3

          -mthumb

          -march=armv7-a

          -mtune=cortex-a9

          83.2%

          4665.6

          -Os

          -funroll-loops

          -marm

          -march=armv5te

          -mtune=cortex-a8

          82.8%

          4630.7

          -Os

          -marm

          -march=armv5te

          -mtune=cortex-a9

          82.2%

          4595.6

          -Os

          -funroll-loops

          -marm

          -march=armv5te

          -mtune=cortex-a9

          81.6%

          4562.7

          -Os

          -funroll-loops

          -marm

          -march=armv7-a

          -mtune=cortex-a8

          81.0%

          4551.7

          -O2

          -mthumb

          -march=armv7-a

          -mtune=cortex-a8

          80.8%

          4521.5

          -Os

          -funroll-loops

          -marm

          -march=armv7-a

          -mtune=cortex-a9

          80.2%

          4519.8

          -Os

          -marm

          -march=armv7-a

          -mtune=cortex-a8

          80.2%

          4500.8

          -Os

          -marm

          -march=armv7-a

          -mtune=cortex-a9

          79.9%

          4237.6

          -O2

          -mthumb

          -march=armv7-a

          -mtune=cortex-a9

          75.2%

          3739.7

          -O2

          -funroll-loops

          -mthumb

          -march=armv5te

          -mtune=cortex-a8

          66.4%

          3730.6

          -O2

          -funroll-loops

          -mthumb

          -march=armv5te

          -mtune=cortex-a9

          66.2%

          3658.8

          -Os

          -mthumb

          -march=armv7-a

          -mtune=cortex-a8

          64.9%

          3657.0

          -Os

          -funroll-loops

          -mthumb

          -march=armv7-a

          -mtune=cortex-a8

          64.9%

          3629.3

          -O2

          -mthumb

          -march=armv5te

          -mtune=cortex-a8

          64.4%

          3585.1

          -Os

          -mthumb

          -march=armv7-a

          -mtune=cortex-a9

          63.6%

          3580.8

          -Os

          -funroll-loops

          -mthumb

          -march=armv7-a

          -mtune=cortex-a9

          63.6%

          3522.2

          -O3

          -mthumb

          -march=armv5te

          -mtune=cortex-a8

          62.5%

          3473.0

          -O2

          -mthumb

          -march=armv5te

          -mtune=cortex-a9

          61.6%

          3338.9

          -O3

          -funroll-loops

          -mthumb

          -march=armv5te

          -mtune=cortex-a8

          59.3%

          3219.1

          -O3

          -funroll-loops

          -mthumb

          -march=armv5te

          -mtune=cortex-a9

          57.1%

          3170.6

          -O3

          -mthumb

          -march=armv5te

          -mtune=cortex-a9

          56.3%

          2753.7

          -Os

          -mthumb

          -march=armv5te

          -mtune=cortex-a8

          48.9%

          2748.6

          -Os

          -funroll-loops

          -mthumb

          -march=armv5te

          -mtune=cortex-a8

          48.8%

          2747.4

          -Os

          -mthumb

          -march=armv5te

          -mtune=cortex-a9

          48.8%

          2743.7

          -Os

          -funroll-loops

          -mthumb

          -march=armv5te

          -mtune=cortex-a9

          48.7%

          Bottom of Form

          http://lion3875.blog.51cto.com/2911026/532719

          http://www.cnx-software.com/2011/04/22/compile-with-arm-thumb2-reduce-memory-footprint-and-improve-performance/#ixzz1qTCwHRc4

          https://wiki.linaro.org/MichaelHope/Sandbox/CoreMark1

          http://blog.csdn.net/itismine/archive/2009/11/01/4753701.aspx

          http://hi.baidu.com/yzx408/blog/item/a050741180944c1cb8127b79.html

          http://houh-1984.blog.163.com/

          32位RISC芯片ARM 體系結(jié)構(gòu)支持兩種指令集:32位的ARM指令集執(zhí)行效率高,對ARM體系架構(gòu)所有功能的完整支持;16位的Thumb指令集是ARM指令集的子集并以良好的代碼密度著稱。如果拋開預(yù)取指令時(shí)間不計(jì),ARM指令相對Thumb指令將有更好的運(yùn)行性能(預(yù)取指令時(shí)需要根據(jù)指令地址偏移量來取指, ARM支持更大的地址偏移量而比較耗時(shí))。最近ARM公司推出的的Thumb-2/Thumb2指令集據(jù)稱是上述兩種特性的綜合,是ARM指令集的性能和Thumb指令集的代碼密度的折中。號(hào)稱達(dá)到98%的ARM性能而又能降低代碼密度達(dá)30%。在目前的大多數(shù)ARM應(yīng)用中依然采用ARM + Thumb代碼的混雜模式。ARM code對應(yīng)的CPU(ARM處理器)工作狀態(tài)稱為ARM State,Thumb對應(yīng)的稱之為Thumb State,這兩種狀態(tài)的不同主要通過CPSR[bit 5]區(qū)別。CPSR(當(dāng)前程序狀態(tài)寄存器)保存了處理器的當(dāng)前工作狀態(tài),[bit 5]也被稱為T bit。對于所有帶有J標(biāo)志的處理器核,比如ARM926EJ-S和ARM1136J-S,J(Jazelle)代表ARM核中集成了Jazelle技 術(shù)。CPSR[bit24]則被成為J bit,如果這位為1,則代表當(dāng)前CPU工作在Java State下而CPU的取指和解碼都是直接操作Java操作數(shù)棧。當(dāng)然要生成Jazelle支持的字節(jié)碼需要特殊的Java編譯器和JVM,一般由第三方 平臺(tái)軟件廠商提供,比如日本的Aplix公司。在ARM處理器的運(yùn)行過程中,匯編指令BX以及BLX可以完成ARM State和Thumb State之間的切換(BXJ和BLXJ完成ARM/Thumb State和Java State之間的切換)。但如果程序有一部分工作在ARM工作狀態(tài)下,一部分工作在Thumb工作狀態(tài)下,而這兩段代碼卻有交互調(diào)用,則在編譯C/C++和匯編源文件時(shí)要 加上 -apcs /interwork選項(xiàng)。ARM公司的ADS(ARM Developer Suite,-apcs /interwork)和RealView的RVDS(RealView Developer Suite,--apcs /interwork) 都支持這樣的編譯選項(xiàng),他們會(huì)在鏈接時(shí)自動(dòng)檢測函數(shù)之間的調(diào)用關(guān)系和工作狀態(tài)提供粘合劑(Veneers)以便程序能夠在不同的工作狀態(tài)下切換。arm-linux-gcc編譯器個(gè)別版本不支持這個(gè)選項(xiàng),所以在開發(fā)ARM + Linux平臺(tái)下使用的程序時(shí)應(yīng)該注意到這個(gè)問題。最后比較了arm-linux-gcc編譯器下ARM(armv7-a)、Thumb-1、Thumb-2指令集以及armv5te、Cortex-A9與Cortex-A8的tune選項(xiàng)效率性能和代碼密度。



          關(guān)鍵詞: ARMThumbThumb-2指令

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();