色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

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

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

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

          本文引用地址:http://cafeforensic.com/article/257034.htm

          ②中斷使能

          下面的例子通過(guò)讀取程序狀態(tài)寄存器PSR并設(shè)置它的中斷使能位bit[7]來(lái)禁止/打開(kāi)中斷。需要注意的是,該例只能運(yùn)行在系統(tǒng)模式下,因?yàn)橛脩裟J绞菬o(wú)權(quán)修改程序狀態(tài)寄存器的。

          __inlinevoidenable_IRQ(void)

          {

          inttmp;

          __asm

          {

          MRStmp,PSR

          BItmp,tmp,#0x80

          MSRCPSR_c,tmp

          }

          }

          __inlinevoiddisable_IRQ(void)

          {

          inttmp;

          __asm

          {

          MRStmp,CPSR

          ORRtmp,tmp,#0x80

          MSRCPSR_c,tmp

          }

          }

          intmain(void)

          {

          disable_IRQ();

          enable_IRQ();

          }

          ③分隔符的計(jì)算

          下面的例子計(jì)算兩個(gè)整數(shù)數(shù)組中分隔符“,”的個(gè)數(shù)。該例子顯示了如何在中訪問(wèn)C或語(yǔ)言中的數(shù)據(jù)類型。該例中的函數(shù)mlal()被編譯器優(yōu)化為一條SMLAL指令,可以使用-S–interleave編譯選項(xiàng)使編譯器輸出匯編結(jié)果。

          #includestdio.h>

          /*changewordorderifbig-endian*/

          #definelo64(a)(((unsigned*)a)[0]) /*longlong型的低32位*/

          #definehi64(a)(((int*)a)[1]) /*longlong型的高32位*/

          __inline__int64mlal(__int64sum,inta,intb)

          {

          #if!defined(__thumb)defined(__TARGET_FEATURE_MULTIPLY)

          __asm

          {

          SMLALlo64(sum),hi64(sum),a,b

          }

          #else

          sum+=(__int64)a*(__int64)b;

          #endif

          returnsum;

          }

          __int64dotprod(int*a,int*b,unsignedn)

          {

          __int64sum=0;

          do

          sum=mlal(sum,*a++,*b++);

          while(--n!=0);

          returnsum;

          }

          inta[10]={1,2,3,4,5,6,7,8,9,10};

          intb[10]={10,9,8,7,6,5,4,3,2,1};

          intmain(void)

          {

          printf(Dotproduct%lld(shouldbe%d)n,dotprod(a,b,10),220);

          return0;

          }

          2.中的限制

          可以在內(nèi)聯(lián)匯編代碼中執(zhí)行的操作有許多限制。這些限制提供安全的方法,并確保在匯編代碼中不違反C和代碼編譯中的假設(shè)。

          ①不能直接向程序計(jì)數(shù)器PC賦值。

          ②內(nèi)聯(lián)匯編不支持標(biāo)號(hào)變量。

          ③不能在程序中使用“.”或{PC}得到當(dāng)前指令地址值。

          ④在16進(jìn)制常量前加“0x”代替“”。

          ⑤建議不要對(duì)堆棧進(jìn)行操作。

          ⑥編譯器可能會(huì)使用r12和r13寄存器存放編譯的中間結(jié)果,在計(jì)算表達(dá)式值時(shí)可能會(huì)將寄存器r0~r3、r12及r14用于子程序調(diào)用。另外在內(nèi)聯(lián)匯編中設(shè)置程序狀態(tài)寄存器CPSR中的標(biāo)志位NZCV時(shí),要特別小心,內(nèi)聯(lián)匯編中的設(shè)置很可能會(huì)和編譯器計(jì)算的表達(dá)式的結(jié)果沖突。

          ⑦用內(nèi)聯(lián)匯編代碼更改處理器模式是可能的。然而,更改處理器模式會(huì)禁止使用C或操作數(shù)或禁止對(duì)已編譯C或C++代碼的調(diào)用,直到將處理器模式更改回原設(shè)置之后之前的函數(shù)庫(kù)才可正常使用。

          ⑧為Thumb狀態(tài)編譯C或C++時(shí),內(nèi)聯(lián)匯編程序不可用且不匯編Thumb指令。

          ⑨盡管可以使用通用協(xié)處理器指令指定VFP或FPA指令,但內(nèi)聯(lián)匯編程序不為它們提供直接支持。

          不能用內(nèi)聯(lián)匯編代碼更改VFP向量模式。內(nèi)聯(lián)匯編可包含浮點(diǎn)表達(dá)式操作數(shù),該操作數(shù)可使用編譯程序生成的VFP代碼求出操作數(shù)值。因此,僅由編譯程序修改VFP狀態(tài)很重要。

          ⑩內(nèi)嵌匯編不支持的指令有BX、BLX、BXJ和BKPT指令。而LDM、STM、LDRD和STRD指令可能被等效為LDR或STR指令。

          3.內(nèi)聯(lián)匯編中的虛擬寄存器

          內(nèi)聯(lián)匯編程序提供對(duì)處理器物理寄存器的非直接訪問(wèn)。如果在內(nèi)聯(lián)匯編程序指令中將某個(gè)寄存器用作操作數(shù),它就成為相同名稱的虛擬寄存器的引用,而不是對(duì)實(shí)際物理ARM寄存器的引用。例如內(nèi)聯(lián)匯編指令中使用了寄存器r0,但對(duì)于C編譯器,指令中出現(xiàn)的r0只是一個(gè)變量,并非實(shí)際的物理寄存器r0,當(dāng)程序運(yùn)行時(shí),可能是由物理寄存器r1來(lái)存放r0所代表的值。

          下面的例子顯示了編譯器如何對(duì)內(nèi)聯(lián)匯編指令的寄存器進(jìn)行分配。

          程序的源代碼如下。

          #includestdio.h>

          voidtest_inline_register(void)

          {

          inti;

          intr5,r6,r7;

          __asm

          {

          MOVi,#0

          loop:

          MOVr5,#0

          MOVr6,#0

          MOVr7,#0

          ADDi,i,#1

          CMPi,#3

          BNEloop

          }

          }

          intmain(void)

          {

          test_inline_register();

          printf(testinlineregistern);

          return0;

          }

          由C編譯器編譯出的匯編碼如下所示。

          test_inline_register:

          0000807CE3A00000MOVr0,#0

          >>>TEST_INLINE_REGISTER#12loop:

          00008080E1A00000NOP

          >>>TEST_INLINE_REGISTER#13MOVr5,#0

          00008084E3A01000MOVr1,#0

          >>>TEST_INLINE_REGISTER#14MOVr6,#0

          00008088E3A02000MOVr2,#0

          >>>TEST_INLINE_REGISTER#15MOVr7,#0

          0000808CE3A03000MOVr3,#0

          >>>TEST_INLINE_REGISTER#16ADDi,i,#1

          00008090E2800001ADDr0,r0,#1

          >>>TEST_INLINE_REGISTER#17CMPi,#3

          00008094E3500003CMPr0,#3

          000080980A000000BEQ0x80a0TEST_INLINE_REGISTER#21>

          >>>TEST_INLINE_REGISTER#18BNEloop

          0000809CEAFFFFF8B0x8084TEST_INLINE_REGISTER#13>

          >>>TEST_INLINE_REGISTER#21}

          000080A0E12FFF1EBXr14

          >>>TEST_INLINE_REGISTER#25{

                  <track id="lbo4i"></track>

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


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




                  評(píng)論


                  相關(guān)推薦

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