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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Thumb指令集之: ARM和Thumb的混合編程

          Thumb指令集之: ARM和Thumb的混合編程

          作者: 時(shí)間:2013-09-30 來(lái)源:網(wǎng)絡(luò) 收藏

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

          上面的例子分為4部分,通過(guò)下面的步驟編譯和運(yùn)行。

          ①使用文本編輯器,如notepad,輸入上面的代碼,并保存成文件addreg.s;

          ②在命令行中鍵入?yún)R編命令armasm–gaddreg.s;

          ③在命令行中鍵入鏈接命令armlinkaddreg.o-oaddreg;

          ④使用調(diào)試器(Debugger)(如,RealViewDebuggerorAXD)運(yùn)行映像文件。可以使用單步執(zhí)行,觀察代碼在Thumb狀態(tài)下的執(zhí)行。

          注意

          Thumb代碼的地址標(biāo)號(hào)如果用偽操作export聲明為“外部的”,則連接器會(huì)自動(dòng)調(diào)整該地址標(biāo)號(hào)使其bit[0]等于1;如果該地址標(biāo)號(hào)沒(méi)有被聲明為“外部的”,則使用者必須手動(dòng)地對(duì)標(biāo)號(hào)進(jìn)行調(diào)整,如上例中的ThumProg+1。

          (5)v5架構(gòu)下的狀態(tài)切換

          v5體系結(jié)構(gòu)的指令集中,增加了下面兩條指令用于和Thumb代碼互交。

          ·BLXaddress

          該指令跳轉(zhuǎn)到指令中指定的地址處執(zhí)行程序并進(jìn)行程序狀態(tài)切換,該地址是“PC相關(guān)的”,地址范圍為±32MB(ARM狀態(tài))或±4MB(Thumb狀態(tài))。

          ·BLXregister

          在該中格式的跳轉(zhuǎn)指令中寄存器Rm指定轉(zhuǎn)移目標(biāo),Rm的第0位拷貝到CPSR中的T位,bit[31:0]移入PC。

          使用上面兩條指令,在執(zhí)行程序跳轉(zhuǎn)之前,處理器自動(dòng)將返回連接寄存器LR的bit[0]位更新為CPSR寄存器的T位,所以無(wú)論處理器狀態(tài)是否發(fā)生變化,程序都能正確返回。

          當(dāng)使用LDR、LDM及POP指令向PC寄存器中賦值時(shí),寄存器CPSR中的Thumb位將被設(shè)置成PC寄存器的bit[0],這時(shí)就實(shí)現(xiàn)了程序狀態(tài)的切換。這種方法在子程序的返回時(shí)非常有效,同樣的指令可以根據(jù)需要返回到ARM狀態(tài)或Thumb狀態(tài)。

          連接器在對(duì)目標(biāo)代碼進(jìn)行連續(xù)時(shí),將代碼中的地址標(biāo)號(hào)分為3類。

          ·ARM指令地址標(biāo)號(hào)。

          ·Thumb指令地址標(biāo)號(hào)。

          ·數(shù)據(jù)(Data)地址標(biāo)號(hào)。

          當(dāng)連接器重定位Thumb代碼中的地址標(biāo)號(hào)時(shí),地址標(biāo)號(hào)的bit[0]位將被自動(dòng)設(shè)置為1。這就意味著跳轉(zhuǎn)指令(這些指令包括BX、BLX和LDR)可以根據(jù)目標(biāo)地址正確的進(jìn)行狀態(tài)切換。

          注意

          上面提到的連接器自動(dòng)設(shè)置目的地址的行為,只有在ARMv5及其以上版本中支持。

          2.使用C和C++語(yǔ)言實(shí)現(xiàn)互交

          對(duì)于不同的C和C++源程序,可以有些程序中包含ARM指令,有些程序中包含Thumb指令,這些程序可以相互調(diào)用,只是在編譯這些程序時(shí)指定--apcs/interwork選項(xiàng)。當(dāng)使用了--apcs/interwork選項(xiàng),編譯器會(huì)自動(dòng)進(jìn)行一些相應(yīng)處理;連接器在檢測(cè)到程序中存在互交工作時(shí),會(huì)生成一些用于程序狀態(tài)切換的代碼。

          (1)代碼編譯

          可以使用下面的指令,將C或C++程序編譯為可以執(zhí)行互交的目標(biāo)代碼。

          armcc--c90--thumb--apcs/interwork

          armcc--c90--arm--apcs/interwork

          armcc--cpp--thumb--apcs/interwork

          armcc--cpp--arm--apcs/interwork

          注意

          --cpp是C++文件(文件后綴為.cpp)默認(rèn)的編譯選項(xiàng)。

          使用--apcs/interwork選項(xiàng)對(duì)文件進(jìn)行編譯時(shí),編譯器會(huì)進(jìn)行如下處理。

          ·對(duì)于葉子程序(leaffunction,即程序中沒(méi)有其他子程序調(diào)用的程序),編譯器將程序中的“MOVPC,LR”指令替換成“BXLR”指令,因?yàn)?ldquo;MOVPC”指令不能進(jìn)行狀態(tài)切換。

          ·對(duì)于非葉子程序,要進(jìn)行一系列的指令替換,如:

          POP{r4,r5,pc}

          替換為:

          POP{r4,r5}

          POP{r3}

          BXr3

          下面的例子顯示了一段帶子程序調(diào)用的C語(yǔ)言程序,使用--apcs/interwork選項(xiàng)進(jìn)行編譯時(shí),對(duì)代碼產(chǎn)生的影響。

          C語(yǔ)言源程序。

          Voidfunc(void)

          {

          ….

          Sub()

          ..

          }

          使用armcc--apcs/interwork選項(xiàng)進(jìn)行編譯產(chǎn)生結(jié)果如下。

          Func

          STMFDsp!,{r4-r7,lr}

          ….

          BLsub

          ….

          LDMFDsp!,{r4-r7,lr}

          BXlr

          使用tcc--apcs/interwork選項(xiàng)進(jìn)行編譯產(chǎn)生結(jié)果如下。

          PUSH{r4-r7,lr}

          ….

          BLsub

          ….

          POP{r4-r7}

          POP{r3}

          BX

          c++相關(guān)文章:c++教程




          評(píng)論


          相關(guān)推薦

          技術(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); })();