Thumb指令集之: ARM和Thumb的混合編程
上面的例子分為4部分,通過下面的步驟編譯和運行。
①使用文本編輯器,如notepad,輸入上面的代碼,并保存成文件addreg.s;
②在命令行中鍵入?yún)R編命令armasm–gaddreg.s;
③在命令行中鍵入鏈接命令armlinkaddreg.o-oaddreg;
④使用調(diào)試器(Debugger)(如,RealViewDebuggerorAXD)運行映像文件??梢允褂脝尾綀?zhí)行,觀察代碼在Thumb狀態(tài)下的執(zhí)行。
注意 | Thumb代碼的地址標號如果用偽操作export聲明為“外部的”,則連接器會自動調(diào)整該地址標號使其bit[0]等于1;如果該地址標號沒有被聲明為“外部的”,則使用者必須手動地對標號進行調(diào)整,如上例中的ThumProg+1。 |
(5)ARMv5架構(gòu)下的狀態(tài)切換
在ARMv5體系結(jié)構(gòu)的指令集中,增加了下面兩條指令用于ARM和Thumb代碼互交。
·BLXaddress
該指令跳轉(zhuǎn)到指令中指定的地址處執(zhí)行程序并進行程序狀態(tài)切換,該地址是“PC相關(guān)的”,地址范圍為±32MB(ARM狀態(tài))或±4MB(Thumb狀態(tài))。
·BLXregister
在該中格式的跳轉(zhuǎn)指令中寄存器Rm指定轉(zhuǎn)移目標,Rm的第0位拷貝到CPSR中的T位,bit[31:0]移入PC。
使用上面兩條指令,在執(zhí)行程序跳轉(zhuǎn)之前,處理器自動將返回連接寄存器LR的bit[0]位更新為CPSR寄存器的T位,所以無論處理器狀態(tài)是否發(fā)生變化,程序都能正確返回。
當使用LDR、LDM及POP指令向PC寄存器中賦值時,寄存器CPSR中的Thumb位將被設(shè)置成PC寄存器的bit[0],這時就實現(xiàn)了程序狀態(tài)的切換。這種方法在子程序的返回時非常有效,同樣的指令可以根據(jù)需要返回到ARM狀態(tài)或Thumb狀態(tài)。
連接器在對目標代碼進行連續(xù)時,將代碼中的地址標號分為3類。
·ARM指令地址標號。
·Thumb指令地址標號。
·數(shù)據(jù)(Data)地址標號。
當連接器重定位Thumb代碼中的地址標號時,地址標號的bit[0]位將被自動設(shè)置為1。這就意味著跳轉(zhuǎn)指令(這些指令包括BX、BLX和LDR)可以根據(jù)目標地址正確的進行狀態(tài)切換。
注意 | 上面提到的連接器自動設(shè)置目的地址的行為,只有在ARMv5及其以上版本中支持。 |
2.使用C和C++語言實現(xiàn)互交
對于不同的C和C++源程序,可以有些程序中包含ARM指令,有些程序中包含Thumb指令,這些程序可以相互調(diào)用,只是在編譯這些程序時指定--apcs/interwork選項。當使用了--apcs/interwork選項,編譯器會自動進行一些相應(yīng)處理;連接器在檢測到程序中存在互交工作時,會生成一些用于程序狀態(tài)切換的代碼。
(1)代碼編譯
可以使用下面的指令,將C或C++程序編譯為可以執(zhí)行互交的目標代碼。
armcc--c90--thumb--apcs/interwork
armcc--c90--arm--apcs/interwork
armcc--cpp--thumb--apcs/interwork
armcc--cpp--arm--apcs/interwork
注意 | --cpp是C++文件(文件后綴為.cpp)默認的編譯選項。 |
使用--apcs/interwork選項對文件進行編譯時,編譯器會進行如下處理。
·對于葉子程序(leaffunction,即程序中沒有其他子程序調(diào)用的程序),編譯器將程序中的“MOVPC,LR”指令替換成“BXLR”指令,因為“MOVPC”指令不能進行狀態(tài)切換。
·對于非葉子程序,要進行一系列的指令替換,如:
POP{r4,r5,pc}
替換為:
POP{r4,r5}
POP{r3}
BXr3
下面的例子顯示了一段帶子程序調(diào)用的C語言程序,使用--apcs/interwork選項進行編譯時,對代碼產(chǎn)生的影響。
C語言源程序。
Voidfunc(void)
{
….
Sub()
..
}
使用armcc--apcs/interwork選項進行編譯產(chǎn)生結(jié)果如下。
Func
STMFDsp!,{r4-r7,lr}
….
BLsub
….
LDMFDsp!,{r4-r7,lr}
BXlr
使用tcc--apcs/interwork選項進行編譯產(chǎn)生結(jié)果如下。
PUSH{r4-r7,lr}
….
BLsub
….
POP{r4-r7}
POP{r3}
BX
c++相關(guān)文章:c++教程
評論