<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

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

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

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

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

②中斷使能

下面的例子通過(guò)讀取程序狀態(tài)寄存器PSR并設置它的中斷使能位bit[7]來(lái)禁止/打開(kāi)中斷。需要注意的是,該例只能運行在系統模式下,因為用戶(hù)模式是無(wú)權修改程序狀態(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();

}

③分隔符的計算

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

#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.中的限制

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

①不能直接向程序計數器PC賦值。

②內聯(lián)匯編不支持標號變量。

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

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

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

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

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

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

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

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

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

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

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

下面的例子顯示了編譯器如何對內聯(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{

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


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




評論


相關(guān)推薦

技術(shù)專(zhuān)區

国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>