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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 混合使用C、C++和匯編語之:內(nèi)聯(lián)匯編和嵌入型匯編的使用

          混合使用C、C++和匯編語之:內(nèi)聯(lián)匯編和嵌入型匯編的使用

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

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

          3.嵌入式匯編程序表達式和++表達式之間的差異

          嵌入式匯編表達式和表達式之間存在以下差異。

          ①匯編程序表達式總是無符號的。相同的表達式在匯編程序和C或中有不同值。例如:

          MOVr0,#(-33554432/2)//結(jié)果為0x7f000000

          MOVr0,#__cpp(-33554432/2)//結(jié)果為0xff000000

          ②以0開頭的匯編程序編碼仍是十進制的。例如:

          MOVr0,#0700//十進制700

          MOVr0,#__cpp(0700)//八進制0700等于十進制448

          ③匯編程序運算符優(yōu)先順序與C和不同。例如:

          MOVr0,#(0x23:AND:0xf+1)//((0x230xf)+1)=>4

          MOVr0,#__cpp(0x230xf+1)//(0x23(0xf+1))=>0

          ④匯編程序字符串不是以空字符為終止標(biāo)志的:

          DCBnotrailingnull//16bytes

          DCB__cpp(Ihaveatrailingnull!!)//25bytes

          注意

          在_cpp標(biāo)識符作用范圍之內(nèi)使用C或C++語法規(guī)則。

          4.嵌入式匯編函數(shù)的生成

          由關(guān)鍵字__asm聲明的嵌入式匯編程序,在編譯時將作為整個文件體傳遞給匯編器。傳遞過程中,__asm函數(shù)的順序保持不變(用模板實例生成的函數(shù)除外)。正是由于嵌入式匯編的這個特性,使得由一個__asm標(biāo)識的嵌入式匯編程序調(diào)用在同一文件中的另一個嵌入式匯編程序是可以實現(xiàn)的。

          當(dāng)使用編譯器armcc時,局部鏈接器(PartialLink)將匯編程序產(chǎn)生的目標(biāo)文件與編譯C程序的目標(biāo)文件相結(jié)合,產(chǎn)生單個目標(biāo)文件。

          編譯程序為每個__asm函數(shù)生成AREA命令。例如,以下__asm函數(shù):

          #includecstddef>

          structX{intx,y;voidaddto_y(int);};

          __asmvoidX::addto_y(int){

          LDRr2,[r0,#__cpp(offsetof(X,y))]

          ADDr1,r2,r1

          STRr1,[r0,#__cpp(offsetof(X,y))]

          BXlr

          }

          對于此函數(shù),編譯程序生成:

          AREA||.emb_text||,CODE,READONLY

          EXPORT|_ZN1X7addto_yEi|

          #linenumfile

          |_ZN1X7addto_yEi|PROC

          LDRr2,[r0,#4]

          ADDr1,r2,r1

          STRr1,[r0,#4]

          BXlr

          ENDP

          END

          由上面的例子可以看出,對于變量offsetof的使用必須加__cpp()標(biāo)識符才能引用,因為該變量是在cstddef頭文件中定義的。

          由__asm聲明的常規(guī)函數(shù)被放在名為.emb_text的段(Section)中。這一點也是嵌入式匯編和最大的不同。相反,隱式實例模板函數(shù)(ImplicitlyInstantiatedTemplateFunction)和函數(shù)放在與函數(shù)名同名的區(qū)域(Area)內(nèi),并為該區(qū)域增加公共屬性。這就確保了這類函數(shù)的特殊語義得以保持。

          由于內(nèi)聯(lián)和模板函數(shù)的區(qū)域的特殊命名,所以這些函數(shù)不按照文件中定義的順序排列,而是任意排序。因此,不能以__asm函數(shù)在原文件中的排列順序,來判斷它們的執(zhí)行順序,也就是說,即使兩個連續(xù)排列的__asm函數(shù),也不一定能順序執(zhí)行。

          5.關(guān)鍵字__cpp

          可用__cpp關(guān)鍵字從匯編代碼中訪問C或C++的編譯時常量表達式,其中包括含有外部鏈接的數(shù)據(jù)或函數(shù)地址。標(biāo)識符__cpp內(nèi)的表達式必須是適合用作C++靜態(tài)初始化的常量表達式(請參閱ISO/IEC14882:1998中的3.6.2非本地對象初始化一節(jié)和本書的常量表達式一節(jié))。

          編譯時,編譯器將使用__cpp(expr)的地方用匯編程序可以使用的常量所取代。例如:

          LDRr0,=__cpp(some_variable)

          LDRr1,=__cpp(some_function)

          BL__cpp(some_function)

          MOVr0,#__cpp(some_constant_expr)

          __cpp表達式中的名稱可在__asm函數(shù)的C++上下文中查閱。__cpp表達式結(jié)果中的任何名稱按照要求被損毀并自動為其生成IMPORT語句。

          6.手動重復(fù)解決方案

          可以在嵌入式匯編中使用C++轉(zhuǎn)換為非虛擬函數(shù)調(diào)用解決重復(fù)。例如:

          voidg(int);

          voidg(long);

          structT{

          intmf(int);

          intmf(int,int);

          };

          __asmvoidf(T*,int,int){

          BL__cpp(static_castint(T::*)(int,int)>(T::mf))//callsT::mf(int,int)

          BL__cpp(static_castvoid(*)(int)>(g))//callsg(int)

          MOVpc,lr

          }

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


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




          評論


          相關(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); })();