版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第8章
C語(yǔ)言編程基礎(chǔ)為了提高程序開(kāi)發(fā)的效率,同時(shí)使程序能與高級(jí)語(yǔ)言接軌,目前所有生產(chǎn)DSP芯片的公司都提供了C語(yǔ)言編譯器。這樣,除了對(duì)于一些運(yùn)算量較大或?qū)\(yùn)算時(shí)間要求很?chē)?yán)格的程序代碼外,一般性的代碼都可采用C語(yǔ)言編程,從而縮短程序的開(kāi)發(fā)周期。C編譯器還同時(shí)提供了匯編語(yǔ)言接口,可使匯編模塊方便地被C語(yǔ)言調(diào)用。(1)C編譯器(2)C代碼優(yōu)化(3)C代碼鏈接(4)C語(yǔ)言(5)C運(yùn)行環(huán)境和庫(kù)函數(shù)以上5部分不再關(guān)注C語(yǔ)言本身的語(yǔ)法,而是關(guān)注如何在CCS集成環(huán)境中對(duì)擁護(hù)已經(jīng)編寫(xiě)好的C代碼有效地進(jìn)行編譯、匯編和鏈接,以生成可執(zhí)行代碼這樣的工程問(wèn)題。CCS開(kāi)發(fā)環(huán)境可以看成是一個(gè)大的軟件包,里面包含了源代碼編輯器,以及工程文件組織、編譯和調(diào)試等一切功能模塊。該軟件包里,shell程序可以完成3個(gè)功能:編譯、匯編和鏈接。shell程序缺省在C盤(pán)安裝時(shí),被安裝在C:\ti\c2400\cgtool子目錄下,對(duì)應(yīng)的文件名為dspcl.exe。 (1)編輯器:包括分析器、優(yōu)化器、代碼產(chǎn)生器。把C語(yǔ)言程序編譯成匯編語(yǔ)言程序。 (2)匯編器:把匯編語(yǔ)言源代碼或C語(yǔ)言已經(jīng)編譯成匯編語(yǔ)言代碼進(jìn)行匯編,以產(chǎn)生COFF目標(biāo)文件。 (3)鏈接器:將文件鏈接,產(chǎn)生可執(zhí)行的目標(biāo)文件。8.1.2Shell程序8.1.3C代碼優(yōu)化
C編譯器中含有一個(gè)C優(yōu)化程序。啟用C優(yōu)化程序可以提高程序執(zhí)行速度,減少C程序代碼長(zhǎng)度。對(duì)于C語(yǔ)言,可以采用簡(jiǎn)化循環(huán),使用軟件流水線(xiàn),重新安排、語(yǔ)句和表達(dá)式以及將變量分配到寄存器等方法實(shí)施優(yōu)化。在CCS中,選擇菜單Project/BuildOptions選項(xiàng),可以直接在彈出的對(duì)話(huà)框中對(duì)優(yōu)先級(jí)別進(jìn)行設(shè)置。8.2C程序代碼鏈接
C編譯器和匯編語(yǔ)言工具為用戶(hù)鏈接程序提供了以下兩種方法。(1)先編譯各個(gè)模塊,最后將他們鏈接在一起。(2)一次執(zhí)行Shell程序的dspcl命令,直接完成各個(gè)模塊的編譯、匯編和鏈接。在CCS集成環(huán)境下,還有少量設(shè)置CCS環(huán)境和工程文件組織工作需要人工干預(yù)。為鏈接C程序,需要DSP開(kāi)發(fā)人員做以下工作:(1)把運(yùn)行支持庫(kù)包含到工程文件中;(2)指定程序運(yùn)行時(shí)的初始化類(lèi)型;(3)確定如何將由C語(yǔ)言程序編譯、匯編和鏈接產(chǎn)生出的可執(zhí)行代碼分配到物理存儲(chǔ)器中。 boot.obj包含了用于初始化運(yùn)行環(huán)境的代碼和數(shù)據(jù)。該模塊執(zhí)行以下任務(wù):(1)建立堆棧;(2)處理運(yùn)行時(shí),初始化表和自動(dòng)初始化全局變量;(3)調(diào)用C語(yǔ)言主程序main();(4)當(dāng)C語(yǔ)言主程序main()結(jié)束時(shí),調(diào)用exit()。
boot.obj中有一個(gè)重要的匯編語(yǔ)言函數(shù)_c_int0。它是boot.obj中的起點(diǎn)。鏈接時(shí),_c_int0被自動(dòng)定義為程序的入口點(diǎn)。如果程序從復(fù)位開(kāi)始運(yùn)行,則應(yīng)將復(fù)位向量轉(zhuǎn)移到_c_int0,以便DSP首先執(zhí)行_c_int0。8.2.2指定初始化類(lèi)型用C語(yǔ)言編程時(shí),會(huì)根據(jù)需要定義全局變量和靜態(tài)變量。有些全局變量和靜態(tài)變量具有初始值,有些全局變量和靜態(tài)變量沒(méi)有初始值。C編譯器對(duì)C程序編譯后,為具有初始值的全局變量和靜態(tài)變量建立了一個(gè)專(zhuān)門(mén)的數(shù)據(jù)塊.cinit。該塊在程序運(yùn)行后調(diào)入到RAM的.bss中。.cinit調(diào)入到RAM中有兩種方法: (1)在運(yùn)行時(shí),自動(dòng)初始化全局變量和靜態(tài)變量; (2)在加載時(shí),自動(dòng)初始化全局變量和靜態(tài)變量。 當(dāng)創(chuàng)建新工程時(shí),第一種是缺省狀態(tài)。8.2.3把塊分配到物理存儲(chǔ)器中把塊分配到物理存儲(chǔ)器中就是把程序和數(shù)據(jù)分配到物理存儲(chǔ)器中。當(dāng)使用C編譯器對(duì)C程序編譯后,可產(chǎn)生數(shù)據(jù)塊和代碼塊。這些塊根據(jù)各種不同的應(yīng)用系統(tǒng)硬件配置和擴(kuò)展情況,可以使用不用的方法將這些塊分配到物理存儲(chǔ)器中。8.3.2創(chuàng)建main()函數(shù)在C語(yǔ)言應(yīng)用軟件中,用戶(hù)必須定義一個(gè)main()函數(shù)作為自己應(yīng)用程序的開(kāi)始。因?yàn)橄到y(tǒng)完成C語(yǔ)言環(huán)境設(shè)置后,boot.obj會(huì)自動(dòng)調(diào)用main()函數(shù)作為程序的開(kāi)始。因此,程序員在程序中編寫(xiě)main()函數(shù)是一種預(yù)定,也是一種強(qiáng)制。voidmain(void){sys_ini();for(;;){delay();/*xf管腳置低*/asm("clrcxf");delay();/*xf管腳置高*/asm("setcxf");}}8.3.3創(chuàng)建2407芯片初始化函數(shù)初始化內(nèi)容包括: (1)2407芯片初始化; (2)工程應(yīng)用中所甬道的片內(nèi)外設(shè)初始化; (3)片內(nèi)外存儲(chǔ)器初始化; (4)應(yīng)用系統(tǒng)硬件接口初始化。8.3.4創(chuàng)建假中斷處理函數(shù)(1)2407工作時(shí),如果意外引發(fā)了內(nèi)核級(jí)中斷,但是卻沒(méi)有低層外設(shè)中斷向量裝入外設(shè)中斷寄存器中時(shí),假中斷向量0000h裝入PIVR;(2)CPU執(zhí)行一個(gè)軟件中斷指令I(lǐng)NTR時(shí),使用了參數(shù)1~6,企圖用軟件中斷去服務(wù)于外設(shè)中斷INT1~INT6。這顯然是一個(gè)錯(cuò)誤,這時(shí),假中斷向量裝入PIVR;(3)中斷請(qǐng)求線(xiàn)發(fā)生故障,外設(shè)發(fā)出中斷請(qǐng)求,而其INTn標(biāo)志卻在CPU應(yīng)答請(qǐng)求之前被軟件清0,此時(shí),外設(shè)中斷的請(qǐng)求可能還沒(méi)有被中斷控制器確認(rèn),中斷控制器也不知道哪個(gè)外設(shè)中斷向量應(yīng)裝PIVR,這時(shí),假中斷向量裝入PIVR
.interruptvoidnothing()//假中斷子程序{return;}8.3.5_c_int0函數(shù)在運(yùn)行C程序之前,用戶(hù)必須首先建立起C語(yǔ)言運(yùn)行環(huán)境。
建立C語(yǔ)言運(yùn)行環(huán)境的函數(shù)在庫(kù)rts2xx.lib中。把_c_int0函數(shù)作為硬件復(fù)位后的中斷矢量入口來(lái)運(yùn)行_c_int0函數(shù)。
rsvectB_c_int0
這樣,當(dāng)系統(tǒng)復(fù)位后,通過(guò)執(zhí)行一條無(wú)條件轉(zhuǎn)移指令來(lái)調(diào)用_c_int0函數(shù),以建立C語(yǔ)言運(yùn)行環(huán)境。_c_int0函數(shù)初始化C環(huán)境時(shí)執(zhí)行了如下任務(wù):
(1)為系統(tǒng)堆棧定義一個(gè)名為.stack的塊,并建立初始化堆棧和幀指針; (2)將.cinit塊的初始化數(shù)據(jù)表中的數(shù)據(jù)復(fù)制到.bss塊,對(duì)全局變量和靜態(tài)變量進(jìn)行初始化; (3)調(diào)用main函數(shù),開(kāi)始運(yùn)行C程序。8.4.2C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)的使用
TI公司的C編譯器提供了C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)。它與boot.asm等一起封裝在rts2xx.lib中。
在使用標(biāo)準(zhǔn)庫(kù)函數(shù)時(shí),首先要聲明這一函數(shù)。TI公司的所有標(biāo)準(zhǔn)庫(kù)函數(shù)以分類(lèi)的形式在不同的頭文件中聲明,全部聲明庫(kù)函數(shù)的頭文件為assert.h、limits.h、stddef.h、ctype.h、math.h、stdlib.h、setjmp.h、string.h、stdarg.h、time.h、和ioports.h。為了使用一個(gè)庫(kù)函數(shù),用戶(hù)必須首先使用#include來(lái)包含聲明函數(shù)的頭文件。8.5TMS320C24xC語(yǔ)言程序開(kāi)發(fā)TMS320C24xC語(yǔ)言具有特定的運(yùn)行環(huán)境,為了確保C語(yǔ)言程序正確運(yùn)行,C語(yǔ)言程序開(kāi)發(fā)必須維護(hù)這個(gè)環(huán)境。8.5.1存儲(chǔ)器模式TMS320C24x的C編譯器將存儲(chǔ)器分為程序存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器。程序存儲(chǔ)器包含可執(zhí)行代碼,數(shù)據(jù)存儲(chǔ)器包含外部變量、靜態(tài)變量和系統(tǒng)堆棧。
由C程序生成的每一塊代碼或數(shù)據(jù)存放于存儲(chǔ)空間的一個(gè)連續(xù)塊中。
存儲(chǔ)器映射及代碼和數(shù)據(jù)存儲(chǔ)空間的分配由鏈接器決定。編譯器不考慮可用存儲(chǔ)空間類(lèi)型,也不考慮存儲(chǔ)空間是否可以被代碼和數(shù)據(jù)使用或者存儲(chǔ)空間是否保留以用于I/O或控制。編譯器只生成可重新分配的代碼,鏈接器完成將代碼和數(shù)據(jù)分配到合適的存儲(chǔ)空間。.text、.cinit和.switch塊通常被鏈接到ROM或RAM,必須處于程序存儲(chǔ)器中;.const塊可以被鏈接到ROM或RAM,但必須處于數(shù)據(jù)存儲(chǔ)器中;.bss、.stack和.sysmem塊必須被鏈接到RAM,并必須處于數(shù)據(jù)存儲(chǔ)器中。這些塊根據(jù)不同的系統(tǒng)配置以不同的方式被放到存儲(chǔ)器中。鏈接器將不同模塊相同的塊組合為輸出塊。完整的程序由這些輸出塊組成,包括匯編器的.data塊。2、C系統(tǒng)堆棧C編譯器使用軟件堆棧實(shí)現(xiàn)以下功能: (1)分配局部變量 (2)給函數(shù)傳遞參數(shù) (3)保存處理器狀態(tài) (4)保存函數(shù)返回值 (5)保存臨時(shí)變量 (6)保存寄存器堆棧運(yùn)行時(shí)從低地址向高地址增加。編譯器使用2個(gè)輔助寄存器管理堆棧: (1)AR1為堆棧指針(SP)。指向當(dāng)前堆棧頂部。 (2)AR0為幀指針(FP)。指向當(dāng)前幀的起始處。每個(gè)函數(shù)調(diào)用會(huì)在堆棧頂創(chuàng)建一個(gè)新的幀,用于保存局部和臨時(shí)變量。4、靜態(tài)和全局變量的存儲(chǔ)器分配在C程序中說(shuō)明的每一個(gè)外部或靜態(tài)變量都是被分配給一個(gè)唯一的連續(xù)空間的,空間的地址由鏈接器確定,編譯器保證這些變量的空間分配多個(gè)字,以便每個(gè)變量按字邊界對(duì)準(zhǔn)。5、結(jié)構(gòu)的對(duì)準(zhǔn)編譯器為結(jié)構(gòu)分配空間時(shí),它將分配足夠的字以包含所有的結(jié)構(gòu)成員。在一組結(jié)構(gòu)中,每個(gè)結(jié)構(gòu)開(kāi)始于字邊界。6、域的對(duì)準(zhǔn)非域類(lèi)型對(duì)準(zhǔn)于字的邊界。對(duì)域分配足夠多的位,相鄰域組裝進(jìn)一個(gè)字的相鄰位,但不跨越兩個(gè)字。如果一個(gè)域要跨越兩個(gè)字,則整個(gè)域?qū)⒎峙涞较乱粋€(gè)字中。8.5.2存儲(chǔ)器規(guī)則
TMS320C2xx編譯器嚴(yán)格規(guī)定:在C語(yǔ)言環(huán)境中,特殊的寄存器和特殊的操作聯(lián)系在一起。如果要將匯編語(yǔ)言與C程序接口,必須遵循對(duì)這些寄存器的規(guī)定。寄存器規(guī)則定義編譯器如何使用寄存器和在函數(shù)調(diào)用時(shí)如何保存值。寄存器使用調(diào)用是否保存AR0幀指針是AR1堆棧指針是AR2局部變量指針?lè)馎R2~AR5表達(dá)式分析否AR6~AR7寄存器變量是Accumulator表達(dá)式分析/返回值否P表達(dá)式分析否T表達(dá)式分析否上表列出了編譯器如何使用寄存器,并說(shuō)明了在函數(shù)調(diào)用時(shí)寄存器在保存值時(shí)所起的具體作用。域名稱(chēng)預(yù)設(shè)值修改ARP輔助寄存器指針1是C進(jìn)位位-是DP數(shù)據(jù)頁(yè)指針-是OV溢出位-是OVM溢出模式-是PM乘積移位模式0否SXM符號(hào)擴(kuò)展模式-是TC測(cè)試控制位-是上表列出了編譯器所使用的所有狀態(tài)位。預(yù)設(shè)值是編譯器在函數(shù)進(jìn)入和返回時(shí)的期望值,修改欄是編譯器產(chǎn)生的代碼是否修改該域。2、堆棧指針、幀指針和局部變量指針編譯器創(chuàng)建和使用自己的軟件堆棧以用于保存函數(shù)返回地址、分配局部變量和給函數(shù)傳遞參數(shù)。當(dāng)函數(shù)需要存儲(chǔ)局部變量時(shí),可以在堆棧中創(chuàng)建自己的工作空間(局部幀)。局部幀在函數(shù)入口時(shí)分配,在函數(shù)返回時(shí)釋放。系統(tǒng)提供堆棧指針(SP)、幀指針(FP)和局部變量指針(LVP)3個(gè)寄存器來(lái)管理堆棧和局部幀。寄存器AR1用做堆棧指針。堆棧從低地址向高地址增長(zhǎng),SP指向堆棧中下一個(gè)可用的字。寄存器AR0用做幀指針。FP指向當(dāng)前函數(shù)局部幀的起始地址。PF直接指向局部幀的第一個(gè)字,該字用做臨時(shí)存儲(chǔ)單元,可以用于實(shí)現(xiàn)寄存器到寄存器值的傳遞,同時(shí)在創(chuàng)建可重入C函數(shù)時(shí)也必須使用該存儲(chǔ)單元。寄存器AR2用做局部變量指針,所有存儲(chǔ)在局部幀的對(duì)象包括參數(shù)都要通過(guò)LVP間接引用。3、寄存器變量寄存器變量是指存儲(chǔ)于寄存器而不是RAM的局部變量或編譯器臨時(shí)變量。(1)不使用優(yōu)化器不使用優(yōu)化器時(shí),編譯器至多為使用register關(guān)鍵字的兩個(gè)變量分配寄存器。變量必須在參數(shù)列表中或函數(shù)的第一塊中定義。編譯器采用AR6和AR7作寄存器變量寄存器。AR6保存第一個(gè)變量,AR7保存第二個(gè)變量。(2)使用優(yōu)化器使用優(yōu)化器時(shí),所有寄存器變量定義將被忽略,由優(yōu)化器決定寄存器分配。優(yōu)化器直接將變量而不是地址分配給寄存器。優(yōu)化器可以將AR5、AR6和AR7用作寄存器變量。AR5在函數(shù)調(diào)用時(shí)不保存,所以它在使用時(shí)可以跨越多個(gè)函數(shù)使用。4、表達(dá)式寄存器編譯器使用沒(méi)有用做寄存器變量的寄存器來(lái)計(jì)算表達(dá)式值和存儲(chǔ)臨時(shí)結(jié)果。在函數(shù)調(diào)用時(shí)不保留表達(dá)式寄存器內(nèi)容。在函數(shù)調(diào)用時(shí),用做臨時(shí)存儲(chǔ)的寄存器保存到局部幀,被調(diào)函數(shù)不用保存和恢復(fù)表達(dá)式寄存器。5、返回值如果函數(shù)返回值為標(biāo)量類(lèi)型(integer、pointer或float),則返回值保存在累加器中。當(dāng)返回值為16位類(lèi)型變量時(shí),返回值在累加器中符號(hào)擴(kuò)展。8.5.3函數(shù)結(jié)構(gòu)和調(diào)用規(guī)則
1、函數(shù)如何進(jìn)行調(diào)用主調(diào)函數(shù)在調(diào)用另一個(gè)函數(shù)時(shí)完成以下工作(ARP必須為AR1):(1)主調(diào)函數(shù)以逆順序?qū)?shù)壓入堆棧(最右邊的參數(shù)最先壓入,最左邊的參數(shù)最后壓入)。函數(shù)調(diào)用時(shí)最左邊的放在堆棧頂部。(2)主調(diào)函數(shù)調(diào)用被調(diào)函數(shù)。(3)主調(diào)函數(shù)假定在函數(shù)返回時(shí)ARP會(huì)被設(shè)定為AR1。(4)當(dāng)被調(diào)函數(shù)結(jié)束,主調(diào)函數(shù)用以下命令將參數(shù)彈出堆棧。SBRKn2、被調(diào)函數(shù)響應(yīng)(函數(shù)入口時(shí)ARP應(yīng)該設(shè)為AR1,AR1用作SP)(1)從硬件堆棧中彈出返回地址,并將其壓入軟件堆棧;(2)將幀指針FP壓入軟件堆棧;(3)分配局部幀;(4)如果被調(diào)函數(shù)修改AR6或AR7,將其壓入堆棧。其他被修改的寄存器可以不保存;(5)執(zhí)行函數(shù)代碼;(6)如果函數(shù)返回標(biāo)量值,將返回值放入累加器。如果返回值為16位整型和指針,在用累加器保存返回值時(shí)進(jìn)行正確的符號(hào)擴(kuò)展;(7)將ARP改為AR1;(8)如果保存了AR6或AR7,則恢復(fù)AR6或AR7;(9)釋放局部幀;(10)恢復(fù)FP;(11)將返回地址從軟件堆棧中彈出并壓入硬件堆棧;(12)返回。 ;假定ARP=AR1POPD*+ ;將返回地址從硬件堆棧彈出,壓入軟件堆棧SARAR0,*+ ;將AR0(FP)壓入堆棧SARAR1,* ;*SP=SPLARAR0,#SIZE ;FP=幀大小LARAR0,*0+ ;FP=SP,SP+=SIZE→分配局部幀空間SARAR6,*+ ;AR6壓棧SARAR7,*+ ;AR7壓棧…… ;函數(shù)代碼MAR*,AR1 ;設(shè)置ARP=SPMAR*- ;指針指向AR7LARAR7,*- ;彈出AR7LARAR6,*- ;彈出AR6SBRKSIZE+1 ;釋放局部幀LARAR0,*- ;彈出局部幀指針FPPSHD* ;將返回地址從軟件堆棧彈出,壓入硬件堆棧RET ;返回8.5.4中斷處理遵循中斷原則就是在不影響C環(huán)境的情況下實(shí)現(xiàn)中斷處理并返回C代碼。c_int0為C程序入口點(diǎn),它同時(shí)也是引導(dǎo)函數(shù),用來(lái)完成C環(huán)境初始化。在初始化工作中,沒(méi)有對(duì)中斷進(jìn)行任何處理,中斷的全部控制寄存器和狀態(tài)位處于缺省狀態(tài)。在缺省狀態(tài)下,中斷沒(méi)有使能。如果系統(tǒng)中要使用中斷,用戶(hù)必須作相應(yīng)處理,使中斷使能。這些操作很容易用asm語(yǔ)句實(shí)現(xiàn),或調(diào)用匯編函數(shù)來(lái)實(shí)現(xiàn),對(duì)C環(huán)境沒(méi)有影響。調(diào)用中斷程序時(shí),首先應(yīng)調(diào)用運(yùn)行時(shí)支持庫(kù)中的子程序I$$SAVE。這個(gè)子程序保存了所有的寄存器。同樣,在中斷程序返回時(shí),應(yīng)調(diào)用調(diào)用運(yùn)行支持庫(kù)中的子程序I$$RET,用于恢復(fù)被保存的寄存器。以上過(guò)程都是自動(dòng)的,不需要用戶(hù)編程時(shí)干預(yù)。
interrupt是C編譯器中的中斷關(guān)鍵字,用來(lái)聲明中斷函數(shù)。格式如下:interruptvoidnothing()//啞中斷子程序{return;}8.6C語(yǔ)言和匯編語(yǔ)言混合編程用C語(yǔ)言和匯編語(yǔ)言的混合編程方法主要有以下四種:(1)獨(dú)立編寫(xiě)C程序和匯編程序,分開(kāi)編譯或匯編形成各自的目標(biāo)代碼模塊,然后用鏈接器將C程序和匯編程序鏈接起來(lái)。(2)直接在C語(yǔ)言程序的相應(yīng)位置嵌入?yún)R編程序。(3)在C語(yǔ)言程序中使用匯編程序的變量。(4)對(duì)C程序進(jìn)行編譯生成相應(yīng)的匯編程序,然后對(duì)匯編程序進(jìn)行手工優(yōu)化和修改。8.6.1獨(dú)立的C和匯編程序模塊接口(1)不論是用C編寫(xiě)的函數(shù)還是匯編編寫(xiě)的函數(shù),都必須遵守寄存器使用規(guī)則。(2)必須保護(hù)C函數(shù)要用到的幾個(gè)特定寄存器。(3)如果要改變狀態(tài)寄存器的任何位,必須確?;謴?fù)出它們的值。(4)中斷程序必須保護(hù)所有用到的寄存器。(5)從匯編程序調(diào)用C函數(shù)時(shí),以逆序方式將參數(shù)壓入堆棧,調(diào)用之后,將參數(shù)彈出。(6)調(diào)用C函數(shù)時(shí),注意C函數(shù)只保護(hù)了幾個(gè)特定的專(zhuān)用寄存器,其他寄存器C函數(shù)可以自由使用。(7)長(zhǎng)整型和俘點(diǎn)數(shù)在存儲(chǔ)器中存放的順序是低位字在低地址,高位字在高地址。(8)如果函數(shù)有返回值,返回值存放在累加器ACC中。(9)匯編模塊不能改變由C產(chǎn)生的.cinit塊。(10)編譯器在所有的標(biāo)識(shí)符(函數(shù)名、變量名等)前加一下劃線(xiàn)“_”。因此,編寫(xiě)匯編語(yǔ)言程序時(shí),必須在C程序可以訪(fǎng)問(wèn)的所有對(duì)象前加“_”。(11)任何在匯編中定義的對(duì)象或函數(shù),如果需要在C中訪(fǎng)問(wèn)或調(diào)用,則必須用匯編指令.global定義。同樣,如果在C中定義的對(duì)象或函數(shù),需要在匯編中訪(fǎng)問(wèn)或調(diào)用,在匯編中也必須用.global定義。(1)C主程序: /*cmian.c*/ externintasmfunc() ;定義外部的匯編函數(shù)
intgvar ;定義全局變量
main() { inti; i=asmfunc(i) ;調(diào)用函數(shù)(2)匯編語(yǔ)言函數(shù)_asmfunc: /*asmsub.c*/ .global_asmfunc .global_gvar .text_asmfunc: POPD*+ ;將返回地址保存至C堆棧 SAR AR0,*+ ;保護(hù)FP SAR AR1,* ;保護(hù)SP LAR AR0,#1 ;幀長(zhǎng)度 LAR AR-,*0+,AR2 ;建立FP和SP LDP #_gvar ;指向_gvar SETC SXM LACC _gvar LAR AR2,#_3 ;參數(shù)偏移 MAR *0+ ;指向參數(shù) ADD *,AR0 ;將參數(shù)加至gvar SACL _gvar MAR *,AR1 SBRK 2 LAR AR0,*- ;恢復(fù)幀指針 PSHD* ;返回地址壓入C24x堆棧 RET .end8.6.2在C語(yǔ)言中直接嵌入語(yǔ)句是一種直接的C和匯編接口方法。可以在C程序中實(shí)現(xiàn)用C語(yǔ)言無(wú)法實(shí)現(xiàn)的一些硬件控制功能。
asm(“匯編語(yǔ)句”)注意以下幾點(diǎn):(1)防止嵌入的asm語(yǔ)句破壞C環(huán)境。(2)在C代碼中插入跳轉(zhuǎn)或標(biāo)號(hào)可能會(huì)影響代碼產(chǎn)生器的寄存器跟蹤算法,產(chǎn)生不可預(yù)測(cè)的結(jié)果。(3)插入影響編譯環(huán)境的偽指令也可能會(huì)造成麻煩。(4)不要改變C變量值,但可以讀取變量值。如上,在程序中直接嵌入?yún)R編語(yǔ)句的典型應(yīng)用是控制芯片的一些硬件資源。#include"exp4_2407.h"voidsys_ini()//系統(tǒng)初始化子程序10008AA0POPD*+100180A0SARAR0,*+10028180SARAR1,*1003B001LARAR0,#1h100400E0LARAR0,*0+{/*關(guān)總中斷*/asm("setcINTM");1005BE41SETCINTM/*抑制符號(hào)位擴(kuò)展*/asm("clrcSXM");1006BE46CLRCSXM/*累加器中結(jié)果正常溢出*/asm("clrcOVM");1007BE42CLRCOVM/*禁止看門(mén)狗*/*WDCR=0x00E8;1008BD00LDP#100h10090300LARAR3,0h100AB9E8LACL#e8h100B8B8BMAR*,AR3100C908CSACL*,0,AR4/*CLKIN=10M,CLKOUT=40M*/*SCSR1=0x0000;100D0401LARAR4,1h100EB900LACL#0h100F9089SACL*,0,AR1}10107C02SBRK#2h10110090LARAR0,*-10127680PSHD*1013EF00RETvoiddelay()10148AA0POPD*+101580A0SARAR0,*+10168180SARAR1,*1017B004LARAR0,#4h101800EALARAR0,*0+,AR2
{
unsignedintk;for(k=0;k<60000;k++);1019B900LACL#0h101AB201LARAR2,#1h101B8BE0MAR*0+101C9080SACL*,0101D6980LACL*101EE302BCND1020h,NOV10208BA0MAR*+102190A0SACL*+,010229890SACH*-,0102373A0LT*+1024C001MPY#1h10257580LPH*1026BE46CLRCSXM1027BF80LACC#ea60h,01029BE05SPAC102AE302BCND1030h,NOV102CE304BCND104bh,GT102E7980B1032h,*1030E3CCBCND104bh,LEQ10327C02SBRK#2h10331080LACC*,01034B801ADD#1h10359080SACL*,01036
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年?yáng)|源縣衛(wèi)生健康局公開(kāi)招聘高層次和急需緊缺人才備考題庫(kù)完整答案詳解
- 2026年建筑行業(yè)社保繳納合同
- 2025年北京協(xié)和醫(yī)院腫瘤內(nèi)科合同制科研助理招聘?jìng)淇碱}庫(kù)完整參考答案詳解
- 2026年航空自由合同
- 天津2025年民生銀行天津分行社會(huì)招聘?jìng)淇碱}庫(kù)有答案詳解
- 交通運(yùn)輸部路網(wǎng)監(jiān)測(cè)與應(yīng)急處置中心2026年度公開(kāi)招聘?jìng)淇碱}庫(kù)及答案詳解1套
- 中國(guó)信息通信研究院2026屆校園招聘80人備考題庫(kù)有答案詳解
- 江西省交通投資集團(tuán)有限責(zé)任公司2025年校園招聘筆試筆試歷年參考題庫(kù)及答案
- 2024年水利部黃河水利委員會(huì)事業(yè)單位招聘高校畢業(yè)生考試真題
- 2025年中國(guó)農(nóng)業(yè)銀行研發(fā)中心社會(huì)招聘7人備考題庫(kù)及答案詳解一套
- 激光熔覆應(yīng)用介紹
- 電除顫臨床操作規(guī)范指南樣本
- 教學(xué)《近似數(shù)》數(shù)學(xué)課件教案
- 2025年西昌市邛海瀘山風(fēng)景名勝區(qū)管理局招聘5名執(zhí)法協(xié)勤人員備考題庫(kù)完整參考答案詳解
- 車(chē)庫(kù)買(mǎi)賣(mài)合同終止協(xié)議書(shū)
- DB32/T 4291-2022特種設(shè)備安全監(jiān)督檢驗(yàn)研究系統(tǒng)紀(jì)檢監(jiān)察基本工作規(guī)范
- 《特異性植物的抗逆機(jī)制》課件
- 喜播教育課程故事
- 公路工程工點(diǎn)標(biāo)準(zhǔn)化管理指南
- 醫(yī)院藥學(xué) 試題及答案 模塊十一藥學(xué)信息服務(wù)題庫(kù)
- 煙草證到期代辦委托書(shū)
評(píng)論
0/150
提交評(píng)論