混合使用C、C++和匯編語(yǔ)之:內(nèi)聯(lián)匯編和嵌入型匯編的使用
10.嵌入式匯編版本間的差異
不同版本的ARM編譯器對(duì)嵌入式匯編程序的語(yǔ)法要求會(huì)有所差異。在具體使用時(shí)請(qǐng)參見相關(guān)文檔。
值得注意的是,目前的嵌入式匯編器已經(jīng)完全支持ARMv6指令集,也就是說可以在嵌入式匯編中使用ARMv6指令集中的指令。
12.1.3內(nèi)聯(lián)匯編中使用SP、LR和PC寄存器的遺留問題
雖然目前的編譯器不支持在內(nèi)聯(lián)匯編中使用SP、LR和PC寄存器,但在RVCTv1.2及其以前的編譯器版本中是允許的。下面的例子顯示了使用早期編譯器版本,在內(nèi)聯(lián)匯編中使用LR寄存器的例子。
voidfunc()
{
intvar;
__asm
{
movvar,lr/*得到func()函數(shù)的返回地址*/
}
}
如果使用RVCTv2.0編譯器編譯上面的代碼,編譯器將報(bào)告以下錯(cuò)誤。
Error:#20:identifierlrisundefined
使用RVCTv2.0版本及其以后的編譯器,要在C或C++代碼中使用匯編訪問SP、LR和PC寄存器可以使用下面幾種方法。
①使用嵌入式匯編代碼。嵌入式匯編支持所有的ARM指令,同時(shí)允許在代碼中訪問SP、LR和PC寄存器。
②在內(nèi)聯(lián)匯編中使用以下一些指令。
·__current_pc():訪問PC寄存器。
·__current_sp():訪問SP寄存器。
·__return_address():訪問LR,返回地址寄存器。
下面給出了兩個(gè)訪問SP、LR和PC寄存器的典型實(shí)例程序。
①使用編譯器給定的指令。
voidprintReg()
{
unsignedintspReg,lrReg,pcReg;
__asm{
MOVspReg,__current_sp()
MOVpcReg,__current_pc()
MOVlrReg,__return_address()
}
printf(SP=0x%Xn,spReg);
printf(PC=0x%Xn,pcReg);
printf(LR=0x%Xn,lrReg);
}
②使用嵌入式匯編。
__asmvoidfunc()
{
MOVr0,lr
...
BXlr
}
使用嵌入式匯編可以使用調(diào)試器捕獲程序的返回地址。
12.1.4內(nèi)聯(lián)匯編代碼與嵌入式匯編代碼之間的差異
本節(jié)總結(jié)了內(nèi)聯(lián)匯編和嵌入式匯編在編譯方法上存在的差異:
·內(nèi)聯(lián)匯編代碼使用高級(jí)處理器抽象,并在代碼生成過程中與C和C++代碼集成。因此,編譯程序?qū)和C++代碼與匯編代碼一起進(jìn)行優(yōu)化。
·與內(nèi)聯(lián)匯編代碼不同,嵌入式匯編代碼從C和C++代碼中分離出來(lái)單獨(dú)進(jìn)行匯編,產(chǎn)生與C和C++源代碼編譯對(duì)象相結(jié)合的編譯對(duì)象。
·可通過編譯程序來(lái)內(nèi)聯(lián)內(nèi)聯(lián)匯編代碼,但無(wú)論是顯式還是隱式,都無(wú)法內(nèi)聯(lián)嵌入式匯編代碼。
表12.1總結(jié)了內(nèi)聯(lián)匯編程序與嵌入式匯編程序之間的主要差異。
表12.1 內(nèi)聯(lián)匯編程序與嵌入式匯編程序之間的主要差異
功能 | 嵌入式匯編程序 | 內(nèi)聯(lián)匯編程序 |
指令集 | ARM和Thumb | 僅支持ARM |
ARM匯編指令偽操作 | 支持 | 不支持 |
ARMv6指令集 | 支持 | 僅支持媒體指令 |
C/C++表達(dá)式 | 只支持常數(shù)表達(dá)式 | 完全支持 |
匯編代碼是否優(yōu)化 | 無(wú)優(yōu)化 | 完全優(yōu)化 |
能否被內(nèi)聯(lián)(Inling) | 不可能 | 有可能被內(nèi)聯(lián) |
續(xù)表
功能 | 嵌入式匯編程序 | 內(nèi)聯(lián)匯編程序 |
寄存器訪問 | 使用指定的物理寄存器,還可以使用PC、LR和SP | 使用虛擬寄存器。不能使用PC、LR和SP寄存器 |
是否自動(dòng)產(chǎn)生返回指令 | 手工添加返回指令 | 指定產(chǎn)生(但不支持BX、BXJ和BLX指令) |
是否支持BKPT指令 | 不直接支持 | 不支持 |
c語(yǔ)言相關(guān)文章:c語(yǔ)言教程
c++相關(guān)文章:c++教程
評(píng)論