DSP原理及應(yīng)用-TMS320DM6437 課件 第五章:TMS320DM6437的C語言程序設(shè)計與優(yōu)化_第1頁
DSP原理及應(yīng)用-TMS320DM6437 課件 第五章:TMS320DM6437的C語言程序設(shè)計與優(yōu)化_第2頁
DSP原理及應(yīng)用-TMS320DM6437 課件 第五章:TMS320DM6437的C語言程序設(shè)計與優(yōu)化_第3頁
DSP原理及應(yīng)用-TMS320DM6437 課件 第五章:TMS320DM6437的C語言程序設(shè)計與優(yōu)化_第4頁
DSP原理及應(yīng)用-TMS320DM6437 課件 第五章:TMS320DM6437的C語言程序設(shè)計與優(yōu)化_第5頁
已閱讀5頁,還剩30頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

DSP原理及應(yīng)用第5章TMS320DM6437的C語言程序設(shè)計與優(yōu)化第5章TMS320DM643的C語言程序設(shè)計與優(yōu)化5.1TMS320C64x系列DSP的C/C++語言的特點5.2TMS320C64x系列DSP的C/C++語言程序設(shè)計基礎(chǔ)5.3運行時環(huán)境5.4DSP的C/C++代碼優(yōu)化5.5C語言與匯編語言混合編程5.6實驗和程序?qū)嵗?.1TMS320C64x系列DSP的C/C++語言的特點5.1.1.TMS320C64x系列C/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_ess,[temp.dep]里描述的“在模板中綁定的二相名”。(9)不能實現(xiàn)模板參數(shù)。(10)不能實現(xiàn)模板的export關(guān)鍵字。(11)用typedef定義的函數(shù)類型不包括成員函數(shù)cv-qualifiers。(12)類成員模板的部分說明不能放在類定義的外部。5.1TMS320C64x系列DSP的C/C++語言的特點5.1.2.數(shù)據(jù)表示1)標(biāo)識符和常量●標(biāo)識符的所有字符都是有意義的并且區(qū)分大小寫,此特征適用于內(nèi)部和外部的所有標(biāo)識符;●源(主機)和執(zhí)行(目標(biāo))字符集為ASCII碼,不存在多字節(jié)字符;●字符常量、字符串常量中的十六進制(Hex)、八進制(Octal)轉(zhuǎn)義序列或者字符串常量具有高達(dá)32位的值;●具有多個字符的字符常量按序列中的最后一個字符來編碼,如:'abc'='c'。5.1TMS320C64x系列DSP的C/C++語言的特點5.1.2.數(shù)據(jù)表示2)數(shù)據(jù)類型類型位數(shù)表示方式取值范圍最小值最大值char,signedchar8ASCII-128127unsignedchar8ASCII0255short162scomplement-3276832767unsignedchar16Binary065535int.signedint322scomplement-21474836482147483647unsignedint32Binary04294967295long,signedlong402scomplement-549755813888549755813887unsignedlong40Binary01099511627775enum322scomplement-21474836482147483647float32IEEE32-bit1.175494e-383.40282346e+38double64IEEE64-bit2.22507385e-3081.79769313e+308longdouble64IEEE64-bit2.22507385e-3081.79769313e+308pointers,references,pointerItodatamembers32Binary00xFFFFFFFF5.2TMS320C64x系列DSP的C/C++語言程序設(shè)計基礎(chǔ)5.2.1TMS320C64x系列C/C++程序結(jié)構(gòu)5.2.1.1.TMS320C64x系列C/C++必須包含的文件一個最小的C應(yīng)用程序項目中必須至少包含以下幾個文件。(1)主程序main.c這個文件必須包含一個main()函數(shù)作為C程序的人口點。(2)連接命令文件.cmd這個文件包含了DSP和目標(biāo)板的存儲器空間的定義以及代碼段、數(shù)據(jù)段是如何分配到這些存儲器空間的。這個文件由用戶自己編輯產(chǎn)生。(3)C運行庫文件rts6200.1ib(或者和DSP兼容的rtsxxx.lib)C運行庫提供了諸如pint等標(biāo)準(zhǔn)C函數(shù)還提供了C環(huán)境下的初始化函數(shù)Cin000。這個文件位于CCS安裝目錄下的\000\gtools\lib子目錄。(4)Vectors.asm如果用戶的程序是準(zhǔn)備寫進外部非易失性存儲器并在上電之后直接運行的,那么還必須包含這個文件5.2TMS320C64x系列DSP的C/C++語言程序設(shè)計基礎(chǔ)5.2.1.2C主程序的一般框架//#include包含語句,定義程序中使用的函數(shù)庫對應(yīng)的.h頭文件#include“函數(shù)庫1”//包含頭文件#include<函數(shù)庫2> …//#define定義程序中所有的宏替換#define宏名指定內(nèi)容//宏定義 …//全局變量聲明 變量類型全局變量名;inti,j; //全局變量定義 …//主函數(shù)main() voidmain(void) { //局部變量定義 … for(;;) //或者使用while(1) { //數(shù)據(jù)的輸入 … //調(diào)用子函數(shù)來處理數(shù)據(jù) … //數(shù)據(jù)的輸出 … } }//本程序的內(nèi)部函數(shù)定義 函數(shù)類型函數(shù)名(函數(shù)參數(shù)列表) { //本函數(shù)的局部變量定義 … //本函數(shù)中的算法 … }//中斷服務(wù)程序(函數(shù))的聲明interruptvoidfunction_name(void);5.2TMS320C64x系列DSP的C/C++語言程序設(shè)計基礎(chǔ)5.2.2TMS320C64x系列C/C++語言關(guān)鍵字5.2.2.1.const關(guān)鍵字TMS320C64xC/C++編譯器支持ISO標(biāo)準(zhǔn)的關(guān)鍵字const,此關(guān)鍵字可以更好地控制對一定的數(shù)據(jù)對象進行存儲分配。用戶可以將const限定詞應(yīng)用到任何變量或者數(shù)組,以確保其值不變。5.2.2.2.cregister關(guān)鍵字TMS320C64xC/C++編譯器擴展了C/C++語言的功能,通過增加cregister關(guān)鍵字允許高級語言可以訪問并控制寄存器。5.2.2.3.innerrupt關(guān)鍵字TMS320C64xC/C++編譯器通過增加inerrupt關(guān)鍵字?jǐn)U展了C/C++語言的功能,該關(guān)鍵字指定一個函數(shù)為一個中斷函數(shù)。5.2.2.4.nea和far關(guān)鍵字T1S320C64xC/C++編譯器通過使用near和far關(guān)鍵字?jǐn)U展了CIC++語言的功能,該關(guān)鍵字來指定函數(shù)如何被調(diào)用。5.2.2.5.restrict關(guān)鍵字為了幫助編譯器確定存儲器相關(guān)性,可以使用restrict關(guān)鍵字來限定指針、引用和數(shù)組。5.2TMS320C64x系列DSP的C/C++語言程序設(shè)計基礎(chǔ)5.2.2TMS320C64x系列C/C++語言關(guān)鍵字5.2.2.6.volatile關(guān)鍵字優(yōu)化器會分析數(shù)據(jù)流,以盡可能地避免存儲器的訪問。如果用戶將依賴于存儲器訪問的代碼寫在C/C++程序中,則必須使用volatile關(guān)鍵字以識別這種訪問。編譯器不會優(yōu)化任何對volatile變量的引用。5.2.2.7.asm語句TMS320C64xC/C++編譯器可以將C6000匯編指令或者偽指令直接嵌入編譯器輸出的匯編語言文件。改功能是對C/C++語言的擴展,即asm語句。5.2TMS320C64x系列DSP的C/C++語言程序設(shè)計基礎(chǔ)5.2.3pragma偽指令pragma偽指令告訴編譯器如何處理特定的函數(shù)、對象或者代碼段。TMS320C64xC/C++編譯器支持下列偽指令:CODE_SECTIONDATA_ALIGNDATA_MEM_BANKDATA_SECTIONFUNC_CANNOTINLINEFUNC_EXTCALLEDFUNC_INTERRUPTTHRESHOLDFUNC_IS_PUREFUNC_IS_SYSTEMFUNC_NEVER_RETURNSFUNC_NOGLOBAL_ASGFUNC_NOIND_ASGINTERRUPTMUST_ITERATENMI_INTERRUPTFROB_ITERATESTRUCT_ALINGUNROLL5.2TMS320C64x系列DSP的C/C++語言程序設(shè)計基礎(chǔ)5.2.4初始化靜態(tài)變量和全局變量ISOC標(biāo)準(zhǔn)要求在程序開始運行前,對沒有明確初始化的靜態(tài)和全局變量必須初始化為0,這一般在程序加載時執(zhí)行。由于加載過程在很大程度上與目標(biāo)應(yīng)用系統(tǒng)特定的環(huán)境有關(guān),編譯器本身對預(yù)初始化變量沒有規(guī)定,預(yù)初始化變量由滿足這些要求的應(yīng)用程序完成。如果加載器不預(yù)初始化變量,則可以使用連接器在目標(biāo)文件中將變量預(yù)初始化為0。例如,在連接命令文件中,在.bss段中填充0值,代碼如下:SECTIONS{….bss:fill=0x00;…}5.3運行時環(huán)境5.3.1存儲器模型TMS320C6000編譯器把整個存儲區(qū)當(dāng)做單個線性存儲塊(linearblock),并將其分為子代碼區(qū)和數(shù)據(jù)區(qū)。由一個C程序產(chǎn)生的子代碼塊和數(shù)據(jù)塊被放在各自連續(xù)的存儲空間中。編譯器假定目標(biāo)存儲器的32位地址空間全是可用的。5.3.1.1.段編譯器生成的可重定位的代碼塊和數(shù)據(jù)塊稱為段,采用不同的方式將段分配到存儲器保持系統(tǒng)配置不變。TMS320C6000編譯器產(chǎn)生如下幾種類型的段。(1)已初始化段已初始化段包含數(shù)據(jù)和可執(zhí)行代碼,C/C++編譯器生成的已初始化段如下?!?cinit段:包括變量初始值和常量值?!?.const段:包括字符串文字,浮點常量和在C/C++語言中被聲明為const的數(shù)據(jù)●.switch段:包含大的switch語句的跳轉(zhuǎn)表?!?text段:包含所有的可執(zhí)行代碼。(2)未初始化段存儲器中的保留空間,程序在運行時用它來創(chuàng)建和存儲變量,C/C++編譯器生成的未初始化的段如下?!?bss段:為全局變量和靜態(tài)變量保留。如果為連接器設(shè)定-c選項,則在程序的開始,引導(dǎo)程序會將cinit段的數(shù)據(jù)(可在OM)復(fù)制到bss段。編譯器定義全局號$bss,并指定它為bss段的起始地址?!?far段:為聲明為far的全局變量和靜態(tài)變量保留?!?stack段:系統(tǒng)棧。該存儲區(qū)用于傳遞函數(shù)的參數(shù)和為局部變量分配存儲器空間?!?sysmem段:為動態(tài)存儲空間分配保留的存儲區(qū)。提請動態(tài)存儲空間分配要求的有malloc、calloc、realloc等函數(shù)。如果C/C++程序未使用這些函數(shù),編譯器便不生成該段。編譯器產(chǎn)生默認(rèn).text、.bss和data段,但C/C++編譯器不使用.data段。可允許用CODE_SECTION和DATA_SECTIONpragma令編譯器生成附加的段。5.3運行時環(huán)境5.3.1.2.C/C++系統(tǒng)棧C/C++編譯器將棧用于以下幾個方面:①保存函數(shù)調(diào)用后的返回值地址;②給局部變量分配存儲空間:③傳遞函數(shù)參數(shù);④保存臨時結(jié)果。5.3.1.3.動態(tài)存儲區(qū)分配動態(tài)存儲器分配不是C語言的標(biāo)準(zhǔn)組成部分。TMS320C6000編譯器提供的運行時支持程序庫包括的函數(shù)有malloc、calloc和realloc,這些函數(shù)允許在運行時為變量動態(tài)地分配存儲器空間。5.3.1.4.存儲器模式(1)小存儲器模式系統(tǒng)的默認(rèn)模式。要求整個.bss段限制在32KB(32768B)范圍的存儲空間內(nèi),也就是程序中靜態(tài)和全局變量所占用的存儲空間必須加起來小于32KB。編譯器在運行初始化期間設(shè)置數(shù)據(jù)頁指針(DP,即B14)指向.bss段的起始地址,然后編譯器便能夠直接尋址訪問bss段中的所有對象,而無須改變DP的值。(2)大存儲器模式不限制.bss段的大小,即靜態(tài)和全局變量的存儲空間的大小不受限制。然而當(dāng)編譯器訪問bss段中的一個全局或靜態(tài)變量時,必須首先將該對象的地址讀出寄存器中。為了完成該任務(wù),需要兩個額外的匯編指令。5.3運行時環(huán)境5.3.2

中斷處理當(dāng)C/C++環(huán)境初始化時,啟動程序并禁止中斷。若系統(tǒng)使用中斷,必須手動設(shè)置所需的中斷允許或手動屏蔽某些中斷。該操作對C/C++環(huán)境沒有影響,也可以使用asm或匯編語言函數(shù)來完成5.3.2.1.中斷中保存寄存器當(dāng)C/C++代碼被中斷時,中斷服務(wù)程序必須保存所有用到的寄存器,該寄存器包括中斷服務(wù)程序使用的、以及中斷服務(wù)程序調(diào)用其他函數(shù)時需要使用的。如果中斷服務(wù)程序是由C/C++語言寫的,編譯器會完成寄存器保存。5.3.2.2.使用C/C++中斷服務(wù)程序C/C++中斷服務(wù)程序和其他C/C++函數(shù)一樣,可以使用局部變量和寄存器變量,但是,不能有參數(shù)和返回值。C/C++中斷服務(wù)程序可以在棧中給局部變量分配32KB空間。例如:interruptvoidexample(void){…}5.3運行時環(huán)境5.3.3

系統(tǒng)的初始化運行一個C/C++程序之前,必須建立C/C++運行時環(huán)境。這個工作是由C/C++引導(dǎo)程序調(diào)用c_int00函數(shù)完成的,該函數(shù)的源代碼包含在boot.asm模塊中,該模塊包含在運行時支持源程序庫rts.src中。系統(tǒng)運行開始,跳轉(zhuǎn)到c_int00函數(shù)或調(diào)用c_int00函數(shù),通常是硬件復(fù)位中斷的中斷服務(wù)程序調(diào)用它。必須把c_int00函數(shù)和另一個對象模塊連接起來。這個連接過程如下:使用-c或者-cr連接選項,并在連接器輸入文件中包含一個標(biāo)準(zhǔn)的運行時支持程序庫。當(dāng)C/C++程序連接完成后,連接器在可執(zhí)行的輸出模塊中將程序入口點的值設(shè)置為符號c_int00,但是這沒有使用硬件復(fù)位中斷服務(wù)程序自動地跳轉(zhuǎn)至c_int00。5.4DSP的C/C++代碼優(yōu)化5.4.1C/C++代碼的優(yōu)化流程在編寫和調(diào)試DSPC/C++程序時,為使C6000代碼獲得最好的性能,一般按圖所示的流程分3個階段,每個階段完成的任務(wù)如下:5.4DSP的C/C++代碼優(yōu)化5.4.2分析C代碼的性能①代碼性能的主要衡量方法之一是代碼運行占用的時間,使用C/C++語言的clock()和printf()函數(shù)可以實現(xiàn)計時和顯示特定代碼的功能,為了達(dá)到這一目的,可以利用獨立的軟件模擬器運行這段代碼。②利用動態(tài)調(diào)試器(debugger)中的剖析(profile)模式,可以得到一個關(guān)于代碼中特定代碼段執(zhí)行情況的統(tǒng)計表;該剖析結(jié)果會存儲在以.vaa為擴展名的文件中。③在CCS中使用動態(tài)調(diào)試器中的中斷、clk寄存器和RUN命令可以跟蹤特定代碼段所占用的CPU時鐘周期數(shù),使用“ViewStistis”來觀察使用的周期數(shù)。④在代碼中影響性能的主要代碼段通常是循環(huán)。優(yōu)化一個循環(huán),最容易的方法是抽出該循環(huán),使之成為一個單獨的可重新編寫、編譯和運行的文件。5.4.3.選用C編譯器提供的優(yōu)化選項優(yōu)化-o:使能軟件流水和其他優(yōu)化方法。-pm:使能程序級優(yōu)化。-mt:使能編譯器假設(shè)程序中沒有數(shù)據(jù)存儲混淆,可進一步優(yōu)化代碼。-mg:使能分析(profile)優(yōu)化代碼。-ms:確保不產(chǎn)生冗余循環(huán),從而減小代碼尺寸。-mh:允許投機執(zhí)行。-mx:使能軟件流水循環(huán)重試,基于循環(huán)次數(shù)對循環(huán)試用多個方案,以便選擇最佳方案。5.4DSP的C/C++代碼優(yōu)化5.4.4軟件流水在編譯代碼時,可以選擇編譯器的-o2或-o3選項,編譯器將根據(jù)程序盡可能地安排軟件流水線。使用軟件流水線還有下面幾點限制:(1)循環(huán)結(jié)構(gòu)不能包含代碼調(diào)用,但可以包含內(nèi)聯(lián)函數(shù);(2)循環(huán)計數(shù)器應(yīng)該是遞減的;(3)循環(huán)結(jié)構(gòu)不能包含break,if語句不能嵌套,條件代碼應(yīng)當(dāng)盡量簡單;(4)循環(huán)結(jié)構(gòu)中不能包含改變循環(huán)計數(shù)器的代碼;(5)循環(huán)體代碼不能過長,因為寄存器(32個)的數(shù)量有限,應(yīng)該分解為多個循環(huán);(6)在軟件流水線的運用上,盡量使復(fù)雜的循環(huán)分解成簡單的小循環(huán),以避免寄存器的數(shù)量不夠;對于過于簡單的循環(huán),應(yīng)該適當(dāng)展開,以增加代碼數(shù)量,增加流水線中的迭代指令。5.4DSP的C/C++代碼優(yōu)化5.4.5使用內(nèi)聯(lián)函數(shù)(Intrinsics)內(nèi)聯(lián)函數(shù)是C64x編譯器提供的專門函數(shù),它們與嵌入式的匯編指令一一對應(yīng),C編譯器以內(nèi)聯(lián)函數(shù)的形式支持所有C語言代碼不易表達(dá)的指令,其目的是快速優(yōu)化C源程序。在C源程序中調(diào)用內(nèi)聯(lián)函數(shù),與調(diào)用一般的函數(shù)相同,只不過內(nèi)聯(lián)函數(shù)名稱前有下劃線作特殊標(biāo)識。當(dāng)匯編指令功能不易采用C語言表達(dá)時,可采用內(nèi)聯(lián)函數(shù)表示。Intrinsics是直接與C6000匯編指令映射的在線函數(shù),不易用C/C++語言實現(xiàn)其功能的匯編指令都有對應(yīng)的intrinsics函數(shù),使用方法與調(diào)用函數(shù)一樣,也可使用C/C++變量。如以下程序:5.4DSP的C/C++代碼優(yōu)化5.4DSP的C/C++代碼優(yōu)化【例5-4】執(zhí)行飽和加法的程序如下,考慮如何精簡代碼。intsadd(intx,inty)intresult;result=x+y;if(((x^y)&0x0000000)==0)if((resultx)&0x0000000)result=(x<0)?0x0000000:mf;returmresult);源程序由普通的C語言代碼寫成,執(zhí)行需要多個周期,利用TMIS320C6000編譯器提供的內(nèi)聯(lián)函數(shù),只需要一條指令就可以完成上述程序功能,可快速優(yōu)化C語言代碼。result=_sadd(x,y)5.4.6調(diào)整數(shù)據(jù)類型C64xDSP內(nèi)部數(shù)據(jù)總線和寄存器寬度是32位的。一般遵守的規(guī)則如下:(1)在使用過程中,注意int和long兩種類型的寬度不一致,long型數(shù)據(jù)為40位,會產(chǎn)生額外的指令和占用更多的功能單元。(2)在使用loopcounts時應(yīng)盡量使其為int型或unsignedint型數(shù)據(jù),以避免不必要的符號位擴展。(3)盡量使用short類型進行乘法運算,因為這種數(shù)據(jù)類型適應(yīng)C6000中的16位乘法器。如進行一次short*short運算只需1個時鐘周期,而進行一次int*int運算則需5個時鐘周期。5.4DSP的C/C++代碼優(yōu)化(4)循環(huán)計數(shù)器應(yīng)使用int或無符號int類型,不用short。(5)short型數(shù)據(jù)的int處理,C64xDSP具有雙16bit擴充功能,芯片能在一個周期內(nèi)完成雙16bit的乘法、加減法、比較和移位等操作。在設(shè)計時,當(dāng)對連續(xù)的short型數(shù)據(jù)流操作時,應(yīng)該轉(zhuǎn)化成對int型數(shù)據(jù)流的操作,這樣一次可以把兩個16位的數(shù)據(jù)讀入一個32位的寄存器,然后用內(nèi)部函數(shù)來對它們處理(如_sub2等)。充分運用雙16bit擴充功能,一次可以進行兩個16bit數(shù)據(jù)的運算,速度將提升一倍。5.4DSP的C/C++代碼優(yōu)化5.4.7基于Cache的程序優(yōu)化C64x系列采用了兩級Cache的存儲器結(jié)構(gòu)用于對程序和數(shù)據(jù)的緩存,Cache的使用較好地解決了低速片外數(shù)據(jù)存儲和高速CPU間的矛盾。對Cache進行優(yōu)化主要是從提高Cache命中率的角度來進行的,如果Cache中的數(shù)據(jù)能多次被重復(fù)利用,即DSP運算單元可直接從高速Cache中訪問數(shù)據(jù),而不需要訪問慢速的存儲器,就避免了DSP的數(shù)據(jù)訪問等待時間。在實際編碼時,一般把L2配置為Cache和SRAM混合使用模式。程序使用的一些關(guān)鍵數(shù)據(jù)段和代碼段放入片內(nèi)內(nèi)存中,在片內(nèi)和片外存儲器中分別設(shè)置一個用于動態(tài)分配內(nèi)存的棧heap,動態(tài)內(nèi)存分配函數(shù)MEM_alloc可以方便地指定在哪個堆棧里開辟動態(tài)內(nèi)存空間。

5.4DSP的C/C++代碼優(yōu)化C語言和匯編語言的混合編程方法主要有以下幾種,(1)獨立編寫C程序和匯編程序,分開編譯或匯編形成各自的目標(biāo)代碼模塊,然后用鏈接器將C模塊和匯編模塊鏈接起來。例如,主程序用C語言編寫,中斷向量文件(vectorasm)用匯編語言編寫。這種方法工作量大,但是比較靈活,能做到對程序的絕對控制。(2)在C/C++代碼中使用內(nèi)核函數(shù)直接調(diào)用匯編語言。(3)在C程序中使用匯編語言變量和常量。(4)在C程序中直接內(nèi)嵌匯編語句。用此種方法可以在C程序中實現(xiàn)C語言無法實現(xiàn)的一些硬件控制功能。5.5.C語言和匯編語言混合編程5.5.1在C/C++代碼中調(diào)用匯編語言模塊C/C++代碼可以訪問定義在匯編語言中的變量和調(diào)用函數(shù),并且匯編代碼可以訪問C/C++的變量和調(diào)用C/C++的函數(shù)。匯編語言和C/C++語言接口需遵循如下的規(guī)則:(1)所有的函數(shù),無論是使用C/C++語言編寫還是匯編語言編寫,都必須遵循寄存器的規(guī)定。(2)必須保存寄存器A10~A15、B3和B10~B15,同時還要保存A3。如果使用常規(guī)的堆棧,則不需要明確保存堆棧。即只要任何被壓入堆棧的值在函數(shù)返回之前被彈回,匯編函數(shù)就可以自由使用堆棧。任何其他寄存器都可以自由使用而無須首先保存它們。(3)中斷程序必須保存它們使用的所有寄存器。5.5.C語言和匯編語言混合編程(4)當(dāng)從匯編語言中調(diào)用一個C/C++函數(shù)時,第一個參數(shù)必須保存到指定的寄存器,其他的參數(shù)置于堆棧中。只有A10~A15和B10~B15被編譯器保存。C/C++函數(shù)能修改任何其他寄存器的內(nèi)容。(5)函數(shù)必須根據(jù)C/C++的聲明返回正確的值。整型和32位的浮點值返回到A4中。雙精度、長雙精度、長整型返回到A5:A4中。結(jié)構(gòu)體的返回是將它們復(fù)制到A3的地址。(6)除了全局變量的自動初始化外,匯編模塊不能使用.cinit段。(7)編譯器將連接名分配到所有的擴展對象。因此,當(dāng)編寫匯編代碼時,必須使用編譯器分配的相同的連接名。在匯編語言中定義的在C/C++語言中訪問或者調(diào)用的對象或者函數(shù),都必須以.def或者.global偽指令聲明。這樣可以將符號定義為外部符號并允許連接器對它識別引用。下例為C/C++語言調(diào)用匯編函數(shù)的程序。C程序:extern”C”{ externintasmfunc(inta); /*聲明外部函數(shù)*/ intgvar=4; /*定義全局變量*/}voidmain(){ inti=5; i=asmfunc(i); /*調(diào)用函數(shù)*/……}匯編程序:.global_asmfunc.global_gvar_asmfunc:LDW*+b14(_gvar),A3NOP4ADDa3,a4,a3STWa3,*b14(_gvar)MVa3,a4Bb3NOP55.5.2用內(nèi)嵌函數(shù)訪問匯編語言TMS320C6000編譯器識別若干的內(nèi)嵌操作。內(nèi)嵌函數(shù)可以表達(dá)C/C++語言中較難處理且不易表達(dá)的匯編語句的含義。內(nèi)嵌操作的使用類似于函數(shù),內(nèi)嵌操作可以像普通函數(shù)一樣使用C/C++變量。內(nèi)嵌操作以下畫線開頭,訪問的方式類似于函數(shù)。例如,intxl,x2,y;y=_sadd(x1,x2);其中內(nèi)嵌函數(shù)int_sadd(intsrcl,intsrc2)對應(yīng)的匯編指令為SADD5.5.C語言和匯編語言混合編程5.5.3在C/C++語言中嵌入?yún)R編語言在C/C++源代碼中,可以使用asm語句將單行的匯編語言插入由編譯器產(chǎn)生的匯編語言文件。該功能是對C/C++語言的擴展,即asm語句。該語句提供了C/C++語言不能提供的對硬件的訪問。asm語句類似于調(diào)用一個名為asm的函數(shù)。其參數(shù)為一個字符串常量。語法格式為:asm("匯編正文"):如:asm("RSBXINTM");/*開中斷*/asm("SSBXXF");/*XF置高電平*/asm("NOP");編譯器將參數(shù)串直接復(fù)制到編譯器的輸出文件,匯編正文必須包含在雙引號內(nèi)。所有的字符串都保持它們原來的定義。使用asm

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論