TMS320C6000系列DSP程序開發(fā)課件_第1頁
TMS320C6000系列DSP程序開發(fā)課件_第2頁
TMS320C6000系列DSP程序開發(fā)課件_第3頁
TMS320C6000系列DSP程序開發(fā)課件_第4頁
TMS320C6000系列DSP程序開發(fā)課件_第5頁
已閱讀5頁,還剩91頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第4章TMS320C6000系列DSP程序開發(fā)4.14.24.34.44.54.6TMS320C6000系列DSP的C/C++語言特點TMS320C6000系列DSP的C/C++語言關(guān)鍵字pragma偽指令初始化靜態(tài)變量和全局變量TMS320C6000系列DSP的C/C++代碼優(yōu)化C/C++語言和匯編語言的混合編程第4章TMS320C6000系列DSP程序開發(fā)4.14.4.1TMS320C6000系列DSP的C/C++語言特點4.1.1TMS320C6000系列DSP的C語言特點1.標(biāo)識符和常量標(biāo)識符的所有字符都是有意義的并且區(qū)分大小寫,此特征適用于內(nèi)部和外部的所有標(biāo)識符;源(主機)和執(zhí)行(目標(biāo))字符集為ASCII碼,不存在多字節(jié)字符;字符常量或者字符串常量中的十六進(jìn)制或者八進(jìn)制轉(zhuǎn)義序列或者字符串常量具有高達(dá)32位的值;具有多個字符的字符常量按序列中的最后一個字符編碼,例如:‘a(chǎn)bc’=‘c’。4.1TMS320C6000系列DSP的C/C++語言特4.1.1TMS320C6000系列DSP的C語言特點2.?dāng)?shù)據(jù)類型表4-1列出了TMS320C6000編譯器中各種標(biāo)量數(shù)據(jù)類型、位數(shù)﹑表示方式及取值范圍,許多取值范圍的值可以作為頭文件limits.h中的標(biāo)準(zhǔn)宏使用。類型位數(shù)表示方式取值范圍最小值最大值char,signedcharunsignedcharshortunsignedshortint,signedintunsignedintlong,signedlongunsignedlongenumfloatdoublelongdoublepointers,references,pointertodatamembers8bits8bits16bits16bits32bits32bits40bits40bits32bits32bits64bits64bits32bitsASCIIASCII2scomplementBinary2scomplementBinary2scomplementBinary2scomplementIEEE32-bitIEEE64-biiIEEE64-bitBinary-1280-327680-21474836480-5497558138880-21474836481.175494e-38?2.22507385e-308?2.22507385e-308?0127255327676553521474836474294967295549755813887109951162777521474836473.40282346e+381.79769313e+3081.79769313e+3080xFFFFFFFF4.1.1TMS320C6000系列DSP的C語言特點24.1.1TMS320C6000系列DSP的C語言特點3.?dāng)?shù)據(jù)轉(zhuǎn)換(1)浮點類型到整型的轉(zhuǎn)換,截取0前面的整數(shù)部分。(2)指針類型和整數(shù)類型之間可以自由轉(zhuǎn)換。4.表達(dá)式(1)當(dāng)兩個帶符號的整數(shù)相除時,如果其中有一個為負(fù),則商為負(fù),余數(shù)的符號與分子的符號相同。斜杠(/)用來求商,百分號(%)用來求余數(shù)。例如:10/-3==-3,-10/3==-310%-3==1,-10%3==-1(2)有符號數(shù)的右移為算術(shù)移位,即保留符號。4.1.1TMS320C6000系列DSP的C語言特點34.1.1TMS320C6000系列DSP的C語言特點5.聲明(1)寄存器存儲類對所有的chars﹑short﹑integer和pointer類型有效。(2)結(jié)構(gòu)體成員被打包為字。(3)整數(shù)類型的位段帶有符號,位段被打包為從高位開始的字,并且不能超越字的邊界。(4)中斷關(guān)鍵字interrupt只能用于沒有參數(shù)的void型函數(shù)。6.預(yù)處理器預(yù)處理器忽略任何不支持的#pragma偽指令。4.1.1TMS320C6000系列DSP的C語言特點54.1.2TMS320C6000系列DSP的C++語言特點TMS320C6000系列DSP編譯器支持ISO標(biāo)準(zhǔn)的C++語言,但與標(biāo)準(zhǔn)的C++又存在不同的特點:(1)并不包括完整的C++標(biāo)準(zhǔn)庫支持,但是包括C子集和基本的語言支持。(2)支持C的庫工具(Clibraryfacilities)的頭文件不包括:<clocale>,<csignal>,<cwctype>,<cwchar>。(3)所包括的C++標(biāo)準(zhǔn)庫頭文件為<typeinfo>﹑<new>和<ciso646>。(4)對bad_cast和bad_type_id的支持并不包括在typeinfo文件中。(5)不支持異常事件的處理。(6)默認(rèn)情況下,禁止運行時類型的信息(RTTI)。RTTI允許在運行時確定各種類型的對象。它可以使用-rtti編譯選項來使能。(7)如果兩個類不相關(guān),reinterpret_cast類型指向其中一個類成員的指針,不允許這個指針再指向另一個類的成員。(8)不支持標(biāo)準(zhǔn)中[tesp.res]和[temp.dep]里描述的“在模板中綁定的二相名”。(9)不能實現(xiàn)模板參數(shù)。(10)不能實現(xiàn)模板的export關(guān)鍵字。(11)用typedef定義的函數(shù)類型不包括成員函數(shù)cv-qualifiers。(12)類成員模板的部分說明不能放在類定義的外部。

4.1.2TMS320C6000系列DSP的C++語言特4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字1.const關(guān)鍵字(1)如果在一個對象定義的同時也指定了關(guān)鍵字volatile(如:

volatileconstintx),volatile關(guān)鍵字被分配到RAM(程序不會修改一個constvolatile的對象,但是程序外部的對象可能會被修改);(2)對象是auto存儲類型(在堆棧中分配)。在以上的兩種情況下,為對象分配存儲空間與不使用const關(guān)鍵字時是相同的。在一個定義中使用const關(guān)鍵字很重要,例如,下面代碼的第一句定義了常量指針p為一個整型的變量,第二句定義了一個變量指針q為一個整型常量:int*constp=

&x;constint*q=

&x;使用const關(guān)鍵字,用戶可以定義大常量表并將他們分配到系統(tǒng)ROM中。例如,分配一個ROM表,可以使用如下的定義:farconstintdigits[]={0,1,2,3,4,5,6,7,8,9};4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字2.cregister關(guān)鍵字當(dāng)對一個對象使用cregister關(guān)鍵字時,編譯器將比較對象名和TMS320C6000的標(biāo)準(zhǔn)控制寄存器列表,如果名字匹配,編譯器將參照控制寄存器產(chǎn)生相應(yīng)的代碼。如果不匹配,編譯器將產(chǎn)生一個錯誤??刂萍拇嫫髁斜硪姳?-2。寄存器描述寄存器描述AMRCSRFADCRFAUCRFMCRGFPGFRICR尋址模式寄存器控制狀態(tài)寄存器(僅C6700)浮點加法器配置寄存器(僅C6700)浮點輔助配置寄存器(僅C6700)浮點乘法器配置寄存器(僅C6400)Galois域多項式產(chǎn)生函數(shù)寄存器中斷清除寄存器IERIFRIRPISRISTPNRP中斷使能寄存器中斷標(biāo)記寄存器中斷返回指針中斷設(shè)置寄存器中斷服務(wù)表指針不可屏蔽中斷返回指針4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字一旦聲明該寄存器,用戶就能夠直接使用該寄存器名。下例為控制寄存器的聲明和使用:

【例4.1】定義和使用控制寄存器。externcregistervolatileunsignedintAMR;externcregistervolatileunsignedintCSR;externcregistervolatileunsignedintIFR;externcregistervolatileunsignedintISR;externcregistervolatileunsignedintICR;externcregistervolatileunsignedintIER;externcregistervolatileunsignedintFADCR;externcregistervolatileunsignedintFAUCR;externcregistervolatileunsignedintFMCR;main(){ printf(”AMR=%x\n”,AMR);}4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字3.interrupt關(guān)鍵字當(dāng)用戶將interrupt關(guān)鍵字使用到函數(shù)的定義上時,編譯器會按照中斷函數(shù)要求的寄存器保存規(guī)則和中斷返回的特殊順序去保存寄存器,然后生成特殊的返回代碼序列。用戶可以將interrupt關(guān)鍵字和定義為void但沒有參數(shù)的函數(shù)一起使用。中斷函數(shù)體可以具有局部變量和自由的使用堆?;蛘呷肿兞?。如:interruptvoidint_handler(){ unsighedintflags;……..}4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字4.near和far關(guān)鍵字語法上,near和far關(guān)鍵字被看做存儲類別的變址數(shù)。它們出現(xiàn)在存儲類別說明符和類型的前、后和中間。這兩個存儲器類別的變址數(shù)不能用于一個定義中。正確的使用實例代碼如下:farstaticintx; staticnearintx; staticintfarx;farintfoo();staticfarintfoo();4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字5.restrict關(guān)鍵字【例4.2】對指針使用關(guān)鍵字restrict。voidfunc1(int*restricta,int*restrictb){ /*此處為函數(shù)func1()的代碼*/}該例代碼中關(guān)鍵字restrict的使用告訴編譯器func1中的指針a和b指向的存儲器范圍不會交迭,即指針變量a和b對存儲器的訪問不會沖突,對一個指針變量的寫操作不會影響另一個指針變量的讀操作。【例4.3】

對數(shù)組使用關(guān)鍵字restrict。voidfunc2(intc[restrict],intd[restrict]){ inti; for(i=0;i<64;i++) //計算數(shù)組的累加和以及數(shù)組d[i]的加1操作

{ c[i]+=d[i]; d[i]+=1;}}4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字6.volatile關(guān)鍵字優(yōu)化器分析數(shù)據(jù)流,盡可能地避免存儲器的訪問。如果用戶將依賴于存儲器訪問的代碼寫在C/C++程序中,則必須使用volatile關(guān)鍵字以識別這種訪問。編譯器不會優(yōu)化任何對volatile變量的引用。下面的代碼中,循環(huán)等待一個讀為oxFF的單元:unsignedint*ctrl;while(*ctrl!=oxFF);該代碼中,*ctrl是一個循環(huán)不變的表達(dá)式,因此該循環(huán)被優(yōu)化為一個單存儲器讀。為了改正這些優(yōu)化,可以定義*ctrl為:volatileunsignedint*ctrl4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字7.a(chǎn)sm語句TMS320C6000的C/C++編譯器可以將TMS320C6000匯編指令或者偽指令直接嵌入編譯器輸出的匯編語言文件。該功能是對C/C++語言的擴(kuò)展,即asm語句。asm語句提供了C/C++語言所不能提供的對硬件的訪問。asm語句類似于調(diào)用一個名為asm的函數(shù),該語句以一個字符串常數(shù)為參數(shù),具體語法格式:asm(“assemblertext”);編譯器將參數(shù)直接復(fù)制到編譯器的輸出文件,匯編正文必須包含在雙引號內(nèi)。所有通常的字符串都保持它們原來的定義。例如,可插入一個包含引號的.string偽指令:asm(“str:.string\”abc\“”);4.2TMS320C6000系列DSP的C/C++語言關(guān)4.3pragma偽指令pragma偽指令告訴編譯器如何處理特定的函數(shù)、對象或者代碼段。TMS320C6000的C/C++編譯器支持下面的偽指令:CODE_SECTIONDATA_ALIGNDATA_MEM_BANKDATA_SECTIONFUNC_CANNOT_INLINEFUNC_EXT_CALLEDFUNC_INTERRUPT_THRESHOLDFUNC_IS_PUREFUNC_IS_SYSTEMFUNC_NEVER_RETURNSFUNC_NO_GLOBAL_ASGFUNC_NO_IND_ASGINTERRUPTMUST_ITERATENMI_INTERRUPTPROB_ITERATESTRUCT_ALIGNUNROLL4.3pragma偽指令pragma偽指令告訴編譯器如何4.3pragma偽指令1.CODE_SECTION指令CODE_SECTION指令用于為命名段中的符號指定空間。該指令在C語言中的語法格式為:#pragmaCODE_SECTION(symbol,”sectionname”);該指令在C++語言中的語法格式為:#pragmaCODE_SECTION(”sectionname”);【例4.4】CODE_SECTION指令使用。C源文件:#pragmaCODE_SECTION(fn,”my_sect”)intfn(intx){returnx;}4.3pragma偽指令1.CODE_SECTION指令4.3pragma偽指令此例使用#pragmaCODE_SECTION(fn,"my_sect"),產(chǎn)生my_sect段,并把fn函數(shù)指定到my_sect段。匯編源文件:.sect”my_sect”.global_fn;***********************************************************************;* FUNCTIONNAME:_fn *;* *;* RegsModified :SP *;* RegsUsed :A4,B3,SP *;* LocalFrameSize :0Args+4Auto+0Save=4byte *;***********************************************************************_fn:;**–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*RET .S2 B3 ;|6|SUB .D2 SP,8,SP ;|4|STW .D2T1A4,*+SP(4) ;|4|ADD .S28,SP,SP ;|6|NOP 2;BRANCHOCCURS ;|6|4.3pragma偽指令此例使用#pragmaCODE4.3pragma偽指令2.DATA_SECTION指令DATA_SECTION指令為命名的段中符號指定空間。該指令在C語言中的語法格式為:#pragmaDATA_SECTION(symbol,“sectionname”);該指令在C++語言中的語法格式為:#pragmaDATA_SECTION(“sectionname”);4.3pragma偽指令2.DATA_SECTION指令4.3pragma偽指令【例4.5】DATA_SECTION指令的使用。C源文件:#pragmaDATA_SECTION(bufferB,”my_sect”)charbufferA[512];charbufferB[512];C++源文件:charbufferA[512];#pragmaDATA_SECTION(”my_sect”)charbufferB[512];匯編源文件:.global _bufferA.bss _bufferA,512,4.global _bufferB_bufferB: .usect”my_sect”,512,44.3pragma偽指令【例4.5】DATA_SEC4.3pragma偽指令3.DATA_ALIGN指令DATA_ALIGN指令把符號對齊到邊界。對齊的邊界是符號默認(rèn)的最大界值或常量,常量是2的整數(shù)次冪。該指令在C語言中的語法如下:#pragmaDATA_ALIGN(symbol,constant);該指令在C++中的語法如下:#pragmaDATA_ALIGN(constant);4.FUNC_CANNOT_INLINE指令FUNC_CANNOT_INLINE指令通知編譯器,該命名的函數(shù)不能擴(kuò)展為直接插入。任何使用pragma命令的函數(shù)會忽略由其他方式指定的直接插入。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。該指令在C語言中的語法格式為:#pragmaFUNC_CANNOT_INLINE(func);該指令在C++語言中的語法格式為:#pragmaFUNC_CANNOT_INLINE;4.3pragma偽指令3.DATA_ALIGN指令4.3pragma偽指令5.FUNC_EXT_CALLED指令FUNC_EXT_CALLED指令指定優(yōu)化器保持這些C/C++函數(shù)或任何由這些C/C++函數(shù)調(diào)用的函數(shù)。這些函數(shù)充當(dāng)C/C++的入口點。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C中,F(xiàn)UNC_EXT_CALLED指令的語法格式如下:#pragmaFUNC_EXT_CALLED(func);在C++中,F(xiàn)UNC_EXT_CALLED指令的語法格式如下:#pragmaFUNC_EXT_CALLED;4.3pragma偽指令5.FUNC_EXT_CALLE4.3pragma偽指令6.FUNC_IS_PURE指令FUNC_IS_PURE指令通知優(yōu)化器,該指令命名的函數(shù)沒有負(fù)面效果,允許優(yōu)化做以下的工作:(1)如果函數(shù)的值不需要的話,刪除對函數(shù)的調(diào)用。(2)刪除重復(fù)的函數(shù)。該指令必須出現(xiàn)在對函數(shù)的任何聲明和應(yīng)用之前。在C中,該指令的語法格式為:#pragmaFUNC_IS_PURE(func);在C++中,該指令的語法格式為:#pragmaFUNC_IS_PURE;4.3pragma偽指令6.FUNC_IS_PURE指令4.3pragma偽指令7.FUNC_IS_SYSTEM指令例如,它可以對多函數(shù)所使用的寄存器做出假定。不能在已經(jīng)修改過的ISO函數(shù)中使用該指令。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式為:#pragmaFUNC_IS_SYSTEM(func);在C++語言中,該指令的語法格式為:#pragmaFUNC_IS_SYSTEM;4.3pragma偽指令7.FUNC_IS_SYSTEM4.3pragma偽指令8.FUNC_NEVER_RETURNS指令FUNC_NEVER_RETURNS指令通知優(yōu)化器,在所有的情況下,函數(shù)不會返回到它的調(diào)用處。例如,一個無限循環(huán)的函數(shù)調(diào)用exit(),將不會返回到調(diào)用處。當(dāng)一個函數(shù)被該指令標(biāo)記后,編譯器不會產(chǎn)生一個函數(shù)的結(jié)束。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式為:#pragmaFUNC_NEVER_RETURNS(func);在C++語言中,該指令的語法格式為:#pragmaFUNC_NEVER_RETURNS;4.3pragma偽指令8.FUNC_NEVER_RET4.3pragma偽指令9.FUNC_NO_GLOBAL_ASG指令FUNC_NO_GLOBAL_ASG指令通知優(yōu)化器,該函數(shù)不會給已經(jīng)定義的全局變量賦值并且不會包含任何asm語句。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C中該指令的語法格式如下:#pragmaFUNC_NO_GLOBAL_ASG(func);在C中該指令的語法格式如下:#pragmaFUNC_NO_GLOBAL_ASG;4.3pragma偽指令9.FUNC_NO_GLOBAL4.3pragma偽指令10.FUNC_NO_IND_ASG指令FUNC_NO_IND_ASG指令通知優(yōu)化器函數(shù)不會通過指針進(jìn)行賦值且不包含任何asm語句。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式如下:#pragmaFUNC_NO_IND_ASG(func);在C++語言中,該指令的語法格式如下:#pragmaFUNC_NO_IND_ASG;4.3pragma偽指令10.FUNC_NO_IND_A4.3pragma偽指令11.INTERRUPT指令I(lǐng)NTERRUPT指令允許用戶直接在C代碼中處理中斷。在C語言中,該指令的語法格式如下:#pragmaINTERRUPT(func);在C++語言中,該指令的語法格式如下:#pragmaINTERRUPT;4.3pragma偽指令11.INTERRUPT指令4.4初始化靜態(tài)變量和全局變量如果加載器不預(yù)初始化變量,則可以使用連接器在目標(biāo)文件中將變量預(yù)初始化為0。例如,在鏈接命令文件中,在.bss段中填充0值,代碼如下:SECTIONS{ … .bss:fill=0x00; …} 4.4初始化靜態(tài)變量和全局變量如果加載器不預(yù)初始化變量,4.4初始化靜態(tài)變量和全局變量帶有常數(shù)類型限定詞const的靜態(tài)和全局變量的處理方法與其他類型的靜態(tài)變量和全局變量不同。沒有明確初始化const的靜態(tài)和全局變量與其他靜態(tài)和全局變量是類似的,因為它們沒有被預(yù)初始化為0,例如:constintzero; /*不一定初始化為0*/然而,由于常量是在名為.const的段中進(jìn)行聲明和初始化的,因此常數(shù)、全局和靜態(tài)變量的初始化是不同的,例如:constintzero=0; /*保證初始化為0*/對應(yīng)于.const段的入口: ...sect….const_zero ...word…04.4初始化靜態(tài)變量和全局變量帶有常數(shù)類型限定詞cons4.5TMS320C6000系列DSP的C/C++代碼優(yōu)化4.5.1C/C++代碼的編寫1.?dāng)?shù)據(jù)類型當(dāng)編寫C代碼時,需要對數(shù)據(jù)類型的尺寸仔細(xì)的考慮。TMS320C6000編譯器的每種數(shù)據(jù)類型尺寸如下(包括有符號和無符號類型):(1)char(字符型):bit(2)short(短整型):16bit(3)int(整型):32bit(4)long(長整型):40bit(5)float(浮點型):32bit(6)double(雙精度型):64bit4.5TMS320C6000系列DSP的C/C++代碼優(yōu)4.5.1C/C++代碼的編寫基于每種數(shù)據(jù)類型的尺寸,在編寫C代碼時應(yīng)遵循以下的規(guī)則:(1)避免在代碼中將int和long類型作為相同的尺寸來處理,因為TMS320C6000編譯器對long類型的數(shù)據(jù)使用40位操作。(2)對于定點乘法輸入,應(yīng)盡可能使用short類型的數(shù)據(jù),因為該數(shù)據(jù)類型為TMS320C6000的16位乘法器提供最有效的使用。(3)對循環(huán)計數(shù)器使用int或者unsignedint數(shù)據(jù)類型,而不使用short或者unsignedshort類型,避免不必要的符號擴(kuò)展指令。4.5.1C/C++代碼的編寫基于每種數(shù)據(jù)類型的尺寸,在4.5.1C/C++代碼的編寫2.分析C代碼的性能使用以下手段可以分析特定代碼段的性能:(1)代碼性能的主要衡量方法之一是代碼運行所占用的時間。使用C語言中clock()和printf()函數(shù)具有計時和顯示特定代碼的功能,為了達(dá)到這一目的,利用獨立的軟件模擬器運行這段代碼。(2)利用動態(tài)調(diào)試器(debugger)中的profile模式,可以得到一個關(guān)于代碼中特定代碼段執(zhí)行情況的統(tǒng)計表。(3)使用動態(tài)調(diào)試器中的中斷﹑clk寄存器和RUNB命令可以跟蹤特定代碼段所占用的CPU時鐘周期數(shù)。(4)在代碼中影響性能的主要代碼段通常是循環(huán)。優(yōu)化一個循環(huán),最容易的方法是抽出此循環(huán),使之成為一個單獨的可重新編寫﹑編譯和運行的文件。4.5.1C/C++代碼的編寫2.分析C代碼的性能4.5.2編譯C/C++代碼編譯工具包括一個外殼程序(cl6x),用于編譯﹑匯編優(yōu)化﹑匯編和程序連接。要激活編譯外殼程序,輸入如下:cl6x[options][filenames][–z[linkeroptions][objectfiles]](1)如果編譯器不能確定兩條指令是否獨立,假設(shè)它們相關(guān)并且順序安排這兩條指令。(2)如果編譯器能確定兩條指令是獨立的,將安排它們并行執(zhí)行。通常編譯器很難確定訪問存儲器的指令是否獨立,以下的方法可以幫助編譯器確定指令是否獨立。(3)使用關(guān)鍵字const標(biāo)識變量的存儲單元不會被函數(shù)改變。const表示一個變量或者變量的存儲單元保持不變。盡可能使用const是編寫代碼的較好方法,因為它使用簡單且可以提高代碼的性能。(4)聯(lián)合使用-pm選項和-o3選項可確定程序級優(yōu)化,所有的源文件都被編譯成稱為模塊的中間文件。由于編譯器訪問到整個程序,因此它可以執(zhí)行幾個在文件級優(yōu)化中很少用的優(yōu)化手段。(5)使用-mt選項是向編譯器說明,在代碼中不存在存儲器相關(guān)性,即允許編譯器在無存儲器相關(guān)性的假設(shè)下改進(jìn)優(yōu)化。4.5.2編譯C/C++代碼編譯工具包括一個外殼程序(c4.5.2編譯C/C++代碼下面通過舉例說明存儲器相關(guān)性的概念。例4.6給出了基本矢量和C代碼,圖4-1給出了其相關(guān)圖。4.5.2編譯C/C++代碼下面通過舉例說明存儲器相關(guān)性4.5.3優(yōu)化C代碼1.使用內(nèi)嵌函數(shù)TMS320C6000提供的內(nèi)嵌函數(shù)是一種直接映射為內(nèi)嵌TMS320C6000匯編指令的特殊函數(shù),可以快速優(yōu)化C/C++代碼。內(nèi)嵌函數(shù)用下劃線(_)開頭,使用方法同調(diào)用普通函數(shù)一樣?!纠?.7】沒有內(nèi)嵌函數(shù)的飽和加法。intsadd(inta,intb){ intresult; result=a+b; if(((a^b)&0x80000000)==0) { if((result^a)&0x80000000) { result=(a<0)?0x80000000:0x7fffffff; } } return(result);}【例4.8】使用內(nèi)嵌函數(shù)的飽和加法。

result=_sadd(a,b);4.5.3優(yōu)化C代碼1.使用內(nèi)嵌函數(shù)4.5.3優(yōu)化C代碼2.軟件流水軟件用于安排循環(huán)指令,使循環(huán)的多次迭代以并行方式執(zhí)行。當(dāng)使用編譯器的-o2和-o3選項時,編譯器使用軟件流水優(yōu)化源代碼并且從程序中收集相關(guān)的優(yōu)化信息。圖4-2為循環(huán)的軟件流水示意圖。4.5.3優(yōu)化C代碼2.軟件流水4.5.3優(yōu)化C代碼(1)循環(huán)計數(shù)下例分別為優(yōu)化前后的代碼:原始代碼:

for(i=0;i<N;i++) /*i=循環(huán)計數(shù)變量,N=循環(huán)次數(shù)*/優(yōu)化后代碼:for(i=N;i!=0;i––) /*逆序計數(shù)*/(2)消除冗余循環(huán)有時編譯器不能夠確定循環(huán)是否總是執(zhí)行大于最小循環(huán)次數(shù),因此,編譯器將會產(chǎn)出兩種版本的循環(huán):①如果循環(huán)計數(shù)值小于最小循環(huán)次數(shù),則執(zhí)行非軟件流水循環(huán)版本;②如果循環(huán)計數(shù)值等于或大于最小循環(huán)次數(shù),則執(zhí)行軟件流水的版本。激活編譯器時可以使用以下的選項將循環(huán)次數(shù)傳給編譯器:用-o3和-pm選項允許優(yōu)化器訪問整個程序或者部分,了解循環(huán)次數(shù)信息;使用-nassert內(nèi)核防止冗余循環(huán)的產(chǎn)生,或者允許編譯器(使用或者未使用-ms選項)軟件流水最內(nèi)層循環(huán)以減少代碼量。4.5.3優(yōu)化C代碼(1)循環(huán)計數(shù)4.5.3優(yōu)化C代碼(3)循環(huán)展開有3種循環(huán)展開的方式:①編譯器可以自動進(jìn)行循環(huán)展開;②可以通過UNROLL偽指令建議編譯器進(jìn)行循環(huán)展開;③可以自己循環(huán)展開C/C++代碼?!纠?.9】三個存儲器操作的矢量加運算。voidvecsum2(short*restrictsum,constshort*restrictin1,constshort*restrictin2,unsignedintN){ inti; for(i=0;i<N;i++) sum[i]=in1[i]+in2[i]; //循環(huán)計算in1[i]與

in2[i]的矢量和}4.5.3優(yōu)化C代碼(3)循環(huán)展開4.5.3優(yōu)化C代碼【例4.10】字對齊矢量和。voidvecsum4(short*restrictsum,constshort*restrictin1,constshort*restrictin2,unsignedintN){ inti; #pragmaMUST_ITERATE(10); for(i=0;i<(N/2);i++) { _amem4(&sum[i])=_add2(_amem4_const(&in[1]),_amem4_const(&in2[i])); }}4.5.3優(yōu)化C代碼【例4.10】字對齊矢量和。4.5.3優(yōu)化C代碼(4)投機執(zhí)行(-mh選項)在循環(huán)嵌套中,只對內(nèi)層的循環(huán)進(jìn)行軟件流水。軟件流水的限制如下:軟件流水可以包含內(nèi)核函數(shù),不能包含函數(shù)的調(diào)用;循環(huán)中不能有條件中斷;循環(huán)中不能有遞增循環(huán)計數(shù)器;循環(huán)體內(nèi)不能修改循環(huán)計數(shù)器,因為在循環(huán)中修改循環(huán)計數(shù)器不能將其轉(zhuǎn)換為遞減計數(shù)的循環(huán);循環(huán)代碼量不能過大,因為代碼量過大,需要的寄存器超過TMS320C6000的規(guī)定個數(shù)不能進(jìn)行軟件流水;寄存器的值生命周期不能太長,否則不能進(jìn)行軟件流水;循環(huán)中不能有復(fù)雜的條件代碼,如果過于復(fù)雜則循環(huán)不能進(jìn)行軟件流水。4.5.3優(yōu)化C代碼(4)投機執(zhí)行(-mh選項)4.6C/C++語言和匯編語言的混合編程4.6.1在C/C++代碼中調(diào)用匯編語言模塊C/C++代碼可以訪問定義在匯編語言中的變量和調(diào)用函數(shù),并且匯編代碼可以訪問C/C++的變量和調(diào)用C/C++的函數(shù)。匯編語言和C/C++語言接口需遵循如下的規(guī)則:所有的函數(shù),無論是使用C/C++語言編寫還是匯編語言編寫,都必須遵循寄存器的規(guī)定。必須保存寄存器A10~A15、B3和B10~B15,同時還要保存A3。如果使用常規(guī)的堆棧,則不需要明確保存堆棧。換句話說,只要任何被壓入堆棧的值在函數(shù)返回之前被彈回,匯編函數(shù)就可以自由使用堆棧。任何其他寄存器都可以自由使用而無需首先保存它們。中斷程序必須保存它們使用的所有寄存器。當(dāng)從匯編語言中調(diào)用一個C/C++函數(shù)時,第一個參數(shù)必須保存到指定的寄存器,其他的參數(shù)置于堆棧中。記住,只有A10~A15和B10~B15被編譯器保存。C/C++函數(shù)能修改任何其他寄存器的內(nèi)容。4.6C/C++語言和匯編語言的混合編程4.6.1在4.6.1在C/C++代碼中調(diào)用匯編語言模塊函數(shù)必須根據(jù)C/C++的聲明返回正確的值。整型和32位的浮點值返回到A4中。雙精度、長雙精度、長整型返回到A5:A4中。結(jié)構(gòu)體的返回是將它們復(fù)制到A3的地址。除了全局變量的自動初始化外,匯編模塊不能使用.cinit段。在C/C++啟動程序假定.cinit段完全由初始化表組成。將其他的信息放入.cinit中將破壞表,并產(chǎn)生不可預(yù)料的結(jié)果。編譯器將連接名分配到所有的擴(kuò)展對象。因此,當(dāng)編寫匯編代碼時,必須使用編譯器分配的相同的連接名。任何在匯編語言中定義的在C/C++語言中訪問或者調(diào)用的對象或者函數(shù),都必須以.def或者.global偽指令聲明。這樣可以將符號定義為外部符號并允許連接器對它識別引用。4.6.1在C/C++代碼中調(diào)用匯編語言模塊函數(shù)必須根據(jù)4.6.1在C/C++代碼中調(diào)用匯編語言模塊【例4.11】

C/C++語言調(diào)用匯編函數(shù)。C程序:extern”C”{ externintasmfunc(inta); /*聲明外部函數(shù)*/ intgvar=4; /*定義全局變量*/}voidmain(){ inti=5; i=asmfunc(i); /*調(diào)用函數(shù)*/……}4.6.1在C/C++代碼中調(diào)用匯編語言模塊【例4.114.6.1在C/C++代碼中調(diào)用匯編語言模塊匯編程序:.global_asmfunc.global_gvar_asmfunc:LDW*+b14(_gvar),A3NOP4ADDa3,a4,a3STWa3,*b14(_gvar)MVa3,a4Bb3NOP54.6.1在C/C++代碼中調(diào)用匯編語言模塊匯編程序:4.6.2用內(nèi)嵌函數(shù)訪問匯編語言TMS320C6000編譯器識別若干的內(nèi)嵌操作。內(nèi)嵌函數(shù)可以表達(dá)C/C++中較難處理且不易表達(dá)的匯編語句的含義。內(nèi)嵌操作的使用類似于函數(shù);可以像普通函數(shù)一樣使用C/C++變量。內(nèi)嵌操作以下劃線開頭,訪問的方式類似于函數(shù)。例如:intx1,x2,y;y=_sadd(x1,x2);4.6.2用內(nèi)嵌函數(shù)訪問匯編語言TMS320C6000編4.6.3C/C++語言中嵌入?yún)R編語言其參數(shù)為一個字符串常量。語法格式為:asm(“匯編正文”);編譯器將參數(shù)串直接復(fù)制到編譯器的輸出文件,匯編正文必須包含在雙引號內(nèi)。所有的字符串都保持它們原來的定義。使用asm語句需要注意以下的事項:特別小心不要破壞C/C++環(huán)境,編譯器不會對插入的指令進(jìn)行檢查。避免在C/C++代碼中插入跳轉(zhuǎn)或者標(biāo)號,因為這樣可能會對插入代碼或周圍的變量產(chǎn)生不可預(yù)測的后果。當(dāng)使用匯編語句時不要改變C/C++代碼變量的值,因為編譯器不檢查此類語句。不要用asm語句插入到改變匯編環(huán)境的匯編偽指令中。避免在C代碼中創(chuàng)建匯編宏指令和用-g選項編譯。C環(huán)境調(diào)試信息和匯編宏擴(kuò)展并不兼容。4.6.3C/C++語言中嵌入?yún)R編語言其參數(shù)為一個字符串4.6.4C/C++語言中訪問匯編語言變量1.訪問匯編語言的全局變量在.bss段或者以.usect命名的段訪問未初始化的變量很直接:(1)使用.bss或者.usect偽指令定義變量;(2)當(dāng)使用.usect時,變量定義在一個非.bss的段內(nèi),必須在C中聲明為far;(3)使用.def或者.global偽指令定義為外部變量;(4)在匯編語言中名字之前以下劃線開頭;(5)在C/C++中,將變量聲明為外部的,然后正常訪問。4.6.4C/C++語言中訪問匯編語言變量1.訪問匯編語4.6.4C/C++語言中訪問匯編語言變量【例4.12】C中訪問匯編語言。C程序:externintvar1; /*外部變量*/farexternintvar2; /*外部變量*/var1=1; /*使用變量*/var2=1; /*使用變量*/ 匯編語言程序: .bss_var1,4,4 ;定義變量 .globalvar1 ;聲明為外部變量_var2.usect”mysect”,4,4 ;定義變量 .global_var2 ;聲明為外部變量4.6.4C/C++語言中訪問匯編語言變量【例4.12】第4章TMS320C6000系列DSP程序開發(fā)4.14.24.34.44.54.6TMS320C6000系列DSP的C/C++語言特點TMS320C6000系列DSP的C/C++語言關(guān)鍵字pragma偽指令初始化靜態(tài)變量和全局變量TMS320C6000系列DSP的C/C++代碼優(yōu)化C/C++語言和匯編語言的混合編程第4章TMS320C6000系列DSP程序開發(fā)4.14.4.1TMS320C6000系列DSP的C/C++語言特點4.1.1TMS320C6000系列DSP的C語言特點1.標(biāo)識符和常量標(biāo)識符的所有字符都是有意義的并且區(qū)分大小寫,此特征適用于內(nèi)部和外部的所有標(biāo)識符;源(主機)和執(zhí)行(目標(biāo))字符集為ASCII碼,不存在多字節(jié)字符;字符常量或者字符串常量中的十六進(jìn)制或者八進(jìn)制轉(zhuǎn)義序列或者字符串常量具有高達(dá)32位的值;具有多個字符的字符常量按序列中的最后一個字符編碼,例如:‘a(chǎn)bc’=‘c’。4.1TMS320C6000系列DSP的C/C++語言特4.1.1TMS320C6000系列DSP的C語言特點2.?dāng)?shù)據(jù)類型表4-1列出了TMS320C6000編譯器中各種標(biāo)量數(shù)據(jù)類型、位數(shù)﹑表示方式及取值范圍,許多取值范圍的值可以作為頭文件limits.h中的標(biāo)準(zhǔn)宏使用。類型位數(shù)表示方式取值范圍最小值最大值char,signedcharunsignedcharshortunsignedshortint,signedintunsignedintlong,signedlongunsignedlongenumfloatdoublelongdoublepointers,references,pointertodatamembers8bits8bits16bits16bits32bits32bits40bits40bits32bits32bits64bits64bits32bitsASCIIASCII2scomplementBinary2scomplementBinary2scomplementBinary2scomplementIEEE32-bitIEEE64-biiIEEE64-bitBinary-1280-327680-21474836480-5497558138880-21474836481.175494e-38?2.22507385e-308?2.22507385e-308?0127255327676553521474836474294967295549755813887109951162777521474836473.40282346e+381.79769313e+3081.79769313e+3080xFFFFFFFF4.1.1TMS320C6000系列DSP的C語言特點24.1.1TMS320C6000系列DSP的C語言特點3.?dāng)?shù)據(jù)轉(zhuǎn)換(1)浮點類型到整型的轉(zhuǎn)換,截取0前面的整數(shù)部分。(2)指針類型和整數(shù)類型之間可以自由轉(zhuǎn)換。4.表達(dá)式(1)當(dāng)兩個帶符號的整數(shù)相除時,如果其中有一個為負(fù),則商為負(fù),余數(shù)的符號與分子的符號相同。斜杠(/)用來求商,百分號(%)用來求余數(shù)。例如:10/-3==-3,-10/3==-310%-3==1,-10%3==-1(2)有符號數(shù)的右移為算術(shù)移位,即保留符號。4.1.1TMS320C6000系列DSP的C語言特點34.1.1TMS320C6000系列DSP的C語言特點5.聲明(1)寄存器存儲類對所有的chars﹑short﹑integer和pointer類型有效。(2)結(jié)構(gòu)體成員被打包為字。(3)整數(shù)類型的位段帶有符號,位段被打包為從高位開始的字,并且不能超越字的邊界。(4)中斷關(guān)鍵字interrupt只能用于沒有參數(shù)的void型函數(shù)。6.預(yù)處理器預(yù)處理器忽略任何不支持的#pragma偽指令。4.1.1TMS320C6000系列DSP的C語言特點54.1.2TMS320C6000系列DSP的C++語言特點TMS320C6000系列DSP編譯器支持ISO標(biāo)準(zhǔn)的C++語言,但與標(biāo)準(zhǔn)的C++又存在不同的特點:(1)并不包括完整的C++標(biāo)準(zhǔn)庫支持,但是包括C子集和基本的語言支持。(2)支持C的庫工具(Clibraryfacilities)的頭文件不包括:<clocale>,<csignal>,<cwctype>,<cwchar>。(3)所包括的C++標(biāo)準(zhǔn)庫頭文件為<typeinfo>﹑<new>和<ciso646>。(4)對bad_cast和bad_type_id的支持并不包括在typeinfo文件中。(5)不支持異常事件的處理。(6)默認(rèn)情況下,禁止運行時類型的信息(RTTI)。RTTI允許在運行時確定各種類型的對象。它可以使用-rtti編譯選項來使能。(7)如果兩個類不相關(guān),reinterpret_cast類型指向其中一個類成員的指針,不允許這個指針再指向另一個類的成員。(8)不支持標(biāo)準(zhǔn)中[tesp.res]和[temp.dep]里描述的“在模板中綁定的二相名”。(9)不能實現(xiàn)模板參數(shù)。(10)不能實現(xiàn)模板的export關(guān)鍵字。(11)用typedef定義的函數(shù)類型不包括成員函數(shù)cv-qualifiers。(12)類成員模板的部分說明不能放在類定義的外部。

4.1.2TMS320C6000系列DSP的C++語言特4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字1.const關(guān)鍵字(1)如果在一個對象定義的同時也指定了關(guān)鍵字volatile(如:

volatileconstintx),volatile關(guān)鍵字被分配到RAM(程序不會修改一個constvolatile的對象,但是程序外部的對象可能會被修改);(2)對象是auto存儲類型(在堆棧中分配)。在以上的兩種情況下,為對象分配存儲空間與不使用const關(guān)鍵字時是相同的。在一個定義中使用const關(guān)鍵字很重要,例如,下面代碼的第一句定義了常量指針p為一個整型的變量,第二句定義了一個變量指針q為一個整型常量:int*constp=

&x;constint*q=

&x;使用const關(guān)鍵字,用戶可以定義大常量表并將他們分配到系統(tǒng)ROM中。例如,分配一個ROM表,可以使用如下的定義:farconstintdigits[]={0,1,2,3,4,5,6,7,8,9};4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字2.cregister關(guān)鍵字當(dāng)對一個對象使用cregister關(guān)鍵字時,編譯器將比較對象名和TMS320C6000的標(biāo)準(zhǔn)控制寄存器列表,如果名字匹配,編譯器將參照控制寄存器產(chǎn)生相應(yīng)的代碼。如果不匹配,編譯器將產(chǎn)生一個錯誤??刂萍拇嫫髁斜硪姳?-2。寄存器描述寄存器描述AMRCSRFADCRFAUCRFMCRGFPGFRICR尋址模式寄存器控制狀態(tài)寄存器(僅C6700)浮點加法器配置寄存器(僅C6700)浮點輔助配置寄存器(僅C6700)浮點乘法器配置寄存器(僅C6400)Galois域多項式產(chǎn)生函數(shù)寄存器中斷清除寄存器IERIFRIRPISRISTPNRP中斷使能寄存器中斷標(biāo)記寄存器中斷返回指針中斷設(shè)置寄存器中斷服務(wù)表指針不可屏蔽中斷返回指針4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字一旦聲明該寄存器,用戶就能夠直接使用該寄存器名。下例為控制寄存器的聲明和使用:

【例4.1】定義和使用控制寄存器。externcregistervolatileunsignedintAMR;externcregistervolatileunsignedintCSR;externcregistervolatileunsignedintIFR;externcregistervolatileunsignedintISR;externcregistervolatileunsignedintICR;externcregistervolatileunsignedintIER;externcregistervolatileunsignedintFADCR;externcregistervolatileunsignedintFAUCR;externcregistervolatileunsignedintFMCR;main(){ printf(”AMR=%x\n”,AMR);}4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字3.interrupt關(guān)鍵字當(dāng)用戶將interrupt關(guān)鍵字使用到函數(shù)的定義上時,編譯器會按照中斷函數(shù)要求的寄存器保存規(guī)則和中斷返回的特殊順序去保存寄存器,然后生成特殊的返回代碼序列。用戶可以將interrupt關(guān)鍵字和定義為void但沒有參數(shù)的函數(shù)一起使用。中斷函數(shù)體可以具有局部變量和自由的使用堆?;蛘呷肿兞?。如:interruptvoidint_handler(){ unsighedintflags;……..}4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字4.near和far關(guān)鍵字語法上,near和far關(guān)鍵字被看做存儲類別的變址數(shù)。它們出現(xiàn)在存儲類別說明符和類型的前、后和中間。這兩個存儲器類別的變址數(shù)不能用于一個定義中。正確的使用實例代碼如下:farstaticintx; staticnearintx; staticintfarx;farintfoo();staticfarintfoo();4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字5.restrict關(guān)鍵字【例4.2】對指針使用關(guān)鍵字restrict。voidfunc1(int*restricta,int*restrictb){ /*此處為函數(shù)func1()的代碼*/}該例代碼中關(guān)鍵字restrict的使用告訴編譯器func1中的指針a和b指向的存儲器范圍不會交迭,即指針變量a和b對存儲器的訪問不會沖突,對一個指針變量的寫操作不會影響另一個指針變量的讀操作?!纠?.3】

對數(shù)組使用關(guān)鍵字restrict。voidfunc2(intc[restrict],intd[restrict]){ inti; for(i=0;i<64;i++) //計算數(shù)組的累加和以及數(shù)組d[i]的加1操作

{ c[i]+=d[i]; d[i]+=1;}}4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字6.volatile關(guān)鍵字優(yōu)化器分析數(shù)據(jù)流,盡可能地避免存儲器的訪問。如果用戶將依賴于存儲器訪問的代碼寫在C/C++程序中,則必須使用volatile關(guān)鍵字以識別這種訪問。編譯器不會優(yōu)化任何對volatile變量的引用。下面的代碼中,循環(huán)等待一個讀為oxFF的單元:unsignedint*ctrl;while(*ctrl!=oxFF);該代碼中,*ctrl是一個循環(huán)不變的表達(dá)式,因此該循環(huán)被優(yōu)化為一個單存儲器讀。為了改正這些優(yōu)化,可以定義*ctrl為:volatileunsignedint*ctrl4.2TMS320C6000系列DSP的C/C++語言關(guān)4.2TMS320C6000系列DSP的C/C++語言關(guān)鍵字7.a(chǎn)sm語句TMS320C6000的C/C++編譯器可以將TMS320C6000匯編指令或者偽指令直接嵌入編譯器輸出的匯編語言文件。該功能是對C/C++語言的擴(kuò)展,即asm語句。asm語句提供了C/C++語言所不能提供的對硬件的訪問。asm語句類似于調(diào)用一個名為asm的函數(shù),該語句以一個字符串常數(shù)為參數(shù),具體語法格式:asm(“assemblertext”);編譯器將參數(shù)直接復(fù)制到編譯器的輸出文件,匯編正文必須包含在雙引號內(nèi)。所有通常的字符串都保持它們原來的定義。例如,可插入一個包含引號的.string偽指令:asm(“str:.string\”abc\“”);4.2TMS320C6000系列DSP的C/C++語言關(guān)4.3pragma偽指令pragma偽指令告訴編譯器如何處理特定的函數(shù)、對象或者代碼段。TMS320C6000的C/C++編譯器支持下面的偽指令:CODE_SECTIONDATA_ALIGNDATA_MEM_BANKDATA_SECTIONFUNC_CANNOT_INLINEFUNC_EXT_CALLEDFUNC_INTERRUPT_THRESHOLDFUNC_IS_PUREFUNC_IS_SYSTEMFUNC_NEVER_RETURNSFUNC_NO_GLOBAL_ASGFUNC_NO_IND_ASGINTERRUPTMUST_ITERATENMI_INTERRUPTPROB_ITERATESTRUCT_ALIGNUNROLL4.3pragma偽指令pragma偽指令告訴編譯器如何4.3pragma偽指令1.CODE_SECTION指令CODE_SECTION指令用于為命名段中的符號指定空間。該指令在C語言中的語法格式為:#pragmaCODE_SECTION(symbol,”sectionname”);該指令在C++語言中的語法格式為:#pragmaCODE_SECTION(”sectionname”);【例4.4】CODE_SECTION指令使用。C源文件:#pragmaCODE_SECTION(fn,”my_sect”)intfn(intx){returnx;}4.3pragma偽指令1.CODE_SECTION指令4.3pragma偽指令此例使用#pragmaCODE_SECTION(fn,"my_sect"),產(chǎn)生my_sect段,并把fn函數(shù)指定到my_sect段。匯編源文件:.sect”my_sect”.global_fn;***********************************************************************;* FUNCTIONNAME:_fn *;* *;* RegsModified :SP *;* RegsUsed :A4,B3,SP *;* LocalFrameSize :0Args+4Auto+0Save=4byte *;***********************************************************************_fn:;**–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*RET .S2 B3 ;|6|SUB .D2 SP,8,SP ;|4|STW .D2T1A4,*+SP(4) ;|4|ADD .S28,SP,SP ;|6|NOP 2;BRANCHOCCURS ;|6|4.3pragma偽指令此例使用#pragmaCODE4.3pragma偽指令2.DATA_SECTION指令DATA_SECTION指令為命名的段中符號指定空間。該指令在C語言中的語法格式為:#pragmaDATA_SECTION(symbol,“sectionname”);該指令在C++語言中的語法格式為:#pragmaDATA_SECTION(“sectionname”);4.3pragma偽指令2.DATA_SECTION指令4.3pragma偽指令【例4.5】DATA_SECTION指令的使用。C源文件:#pragmaDATA_SECTION(bufferB,”my_sect”)charbufferA[512];charbufferB[512];C++源文件:charbufferA[512];#pragmaDATA_SECTION(”my_sect”)charbufferB[512];匯編源文件:.global _bufferA.bss _bufferA,512,4.global _bufferB_bufferB: .usect”my_sect”,512,44.3pragma偽指令【例4.5】DATA_SEC4.3pragma偽指令3.DATA_ALIGN指令DATA_ALIGN指令把符號對齊到邊界。對齊的邊界是符號默認(rèn)的最大界值或常量,常量是2的整數(shù)次冪。該指令在C語言中的語法如下:#pragmaDATA_ALIGN(symbol,constant);該指令在C++中的語法如下:#pragmaDATA_ALIGN(constant);4.FUNC_CANNOT_INLINE指令FUNC_CANNOT_INLINE指令通知編譯器,該命名的函數(shù)不能擴(kuò)展為直接插入。任何使用pragma命令的函數(shù)會忽略由其他方式指定的直接插入。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。該指令在C語言中的語法格式為:#pragmaFUNC_CANNOT_INLINE(func);該指令在C++語言中的語法格式為:#pragmaFUNC_CANNOT_INLINE;4.3pragma偽指令3.DATA_ALIGN指令4.3pragma偽指令5.FUNC_EXT_CALLED指令FUNC_EXT_CALLED指令指定優(yōu)化器保持這些C/C++函數(shù)或任何由這些C/C++函數(shù)調(diào)用的函數(shù)。這些函數(shù)充當(dāng)C/C++的入口點。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C中,F(xiàn)UNC_EXT_CALLED指令的語法格式如下:#pragmaFUNC_EXT_CALLED(func);在C++中,F(xiàn)UNC_EXT_CALLED指令的語法格式如下:#pragmaFUNC_EXT_CALLED;4.3pragma偽指令5.FUNC_EXT_CALLE4.3pragma偽指令6.FUNC_IS_PURE指令FUNC_IS_PURE指令通知優(yōu)化器,該指令命名的函數(shù)沒有負(fù)面效果,允許優(yōu)化做以下的工作:(1)如果函數(shù)的值不需要的話,刪除對函數(shù)的調(diào)用。(2)刪除重復(fù)的函數(shù)。該指令必須出現(xiàn)在對函數(shù)的任何聲明和應(yīng)用之前。在C中,該指令的語法格式為:#pragmaFUNC_IS_PURE(func);在C++中,該指令的語法格式為:#pragmaFUNC_IS_PURE;4.3pragma偽指令6.FUNC_IS_PURE指令4.3pragma偽指令7.FUNC_IS_SYSTEM指令例如,它可以對多函數(shù)所使用的寄存器做出假定。不能在已經(jīng)修改過的ISO函數(shù)中使用該指令。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式為:#pragmaFUNC_IS_SYSTEM(func);在C++語言中,該指令的語法格式為:#pragmaFUNC_IS_SYSTEM;4.3pragma偽指令7.FUNC_IS_SYSTEM4.3pragma偽指令8.FUNC_NEVER_RETURNS指令FUNC_NEVER_RETURNS指令通知優(yōu)化器,在所有的情況下,函數(shù)不會返回到它的調(diào)用處。例如,一個無限循環(huán)的函數(shù)調(diào)用exit(),將不會返回到調(diào)用處。當(dāng)一個函數(shù)被該指令標(biāo)記后,編譯器不會產(chǎn)生一個函數(shù)的結(jié)束。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式為:#pragmaFUNC_NEVER_RETURNS(func);在C++語言中,該指令的語法格式為:#pragmaFUNC_NEVER_RETURNS;4.3pragma偽指令8.FUNC_NEVER_RET4.3pragma偽指令9.FUNC_NO_GLOBAL_ASG指令FUNC_NO_GLOBAL_ASG指令通知優(yōu)化器,該函數(shù)不會給已經(jīng)定義的全局變量賦值并且不會包含任何asm語句。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C中該指令的語法格式如下:#pragmaFUNC_NO_GLOBAL_ASG(func);在C中該指令的語法格式如下:#pragmaFUNC_NO_GLOBAL_ASG;4.3pragma偽指令9.FUNC_NO_GLOBAL4.3pragma偽指令10.FUNC_NO_IND_ASG指令FUNC_NO_IND_ASG指令通知優(yōu)化器函數(shù)不會通過指針進(jìn)行賦值且不包含任何asm語句。該指令必須出現(xiàn)在對函數(shù)的任何聲明和引用之前。在C語言中,該指令的語法格式如下:#pragmaFUNC_NO_IND_ASG(func);在C++語言中,該指令的語法格式如下:#pragmaFUNC_NO_IND_ASG;4.3pragma偽指令10.FUNC_N

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論