




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第第8章章 C語言編程基礎(chǔ)語言編程基礎(chǔ) 為了提高程序開發(fā)的效率,同時(shí)使程序能與高級(jí)語言接軌,目前所有生為了提高程序開發(fā)的效率,同時(shí)使程序能與高級(jí)語言接軌,目前所有生產(chǎn)產(chǎn)DSP芯片的公司都提供了芯片的公司都提供了C語言編譯器。這樣,除了對(duì)于一些運(yùn)算量較大語言編譯器。這樣,除了對(duì)于一些運(yùn)算量較大或?qū)\(yùn)算時(shí)間要求很嚴(yán)格的程序代碼外,一般性的代碼都可采用或?qū)\(yùn)算時(shí)間要求很嚴(yán)格的程序代碼外,一般性的代碼都可采用C語言編程,語言編程,從而縮短程序的開發(fā)周期。從而縮短程序的開發(fā)周期。C編譯器還同時(shí)提供了匯編語言接口,可使匯編編譯器還同時(shí)提供了匯編語言接口,可使匯編模塊方便地被模塊方便地被C語言調(diào)用。語言調(diào)用
2、。(1C編譯器編譯器(2C代碼優(yōu)化代碼優(yōu)化(3C代碼鏈接代碼鏈接(4C語言語言(5C運(yùn)行環(huán)境和庫函數(shù)運(yùn)行環(huán)境和庫函數(shù) 以上以上5部分不再關(guān)注部分不再關(guān)注C語言本身的語法,而是關(guān)注如何在語言本身的語法,而是關(guān)注如何在CCS集成環(huán)境集成環(huán)境中對(duì)擁護(hù)已經(jīng)編寫好的中對(duì)擁護(hù)已經(jīng)編寫好的C代碼有效地進(jìn)行編譯、匯編和鏈接,以生成可執(zhí)行代碼有效地進(jìn)行編譯、匯編和鏈接,以生成可執(zhí)行代碼這樣的工程問題。代碼這樣的工程問題。8.1 C編譯器和編譯器和C優(yōu)化代碼優(yōu)化代碼8.1.1 C編譯器特性編譯器特性 C編譯器的主要功能是將用戶編寫的編譯器的主要功能是將用戶編寫的C語言代碼翻譯為匯編語言程序。語言代碼翻譯為匯編語言
3、程序。(1支持支持ANSI標(biāo)準(zhǔn)標(biāo)準(zhǔn)C。 (2支持支持ANSI標(biāo)準(zhǔn)實(shí)時(shí)運(yùn)行庫。標(biāo)準(zhǔn)實(shí)時(shí)運(yùn)行庫。 (3匯編程序輸出。匯編程序輸出。 (4生成生成COFF目標(biāo)文件。目標(biāo)文件。(5編譯器的編譯器的Shell程序。程序。(6靈活的匯編語言接口。靈活的匯編語言接口。(7完整的預(yù)處理程序。完整的預(yù)處理程序。(8最優(yōu)化。最優(yōu)化。(9初始化數(shù)據(jù)到初始化數(shù)據(jù)到ROM存儲(chǔ)器中。存儲(chǔ)器中。(10原程序交互列表功能。原程序交互列表功能。(11庫構(gòu)造工具。庫構(gòu)造工具。 CCS開發(fā)環(huán)境可以看成是一個(gè)大的軟件包,里面包含了源代碼開發(fā)環(huán)境可以看成是一個(gè)大的軟件包,里面包含了源代碼編輯器,以及工程文件組織、編譯和調(diào)試等一切功能模
4、塊。該軟件編輯器,以及工程文件組織、編譯和調(diào)試等一切功能模塊。該軟件包里,包里,shell程序可以完成程序可以完成3個(gè)功能:編譯、匯編和鏈接。個(gè)功能:編譯、匯編和鏈接。shell程序程序缺省在缺省在C盤安裝時(shí),被安裝在盤安裝時(shí),被安裝在C:tic2400cgtool子目錄下,對(duì)應(yīng)的子目錄下,對(duì)應(yīng)的文件名為文件名為dspcl.exe。(1編輯器:包括分析器、優(yōu)化器、代碼產(chǎn)生器。把編輯器:包括分析器、優(yōu)化器、代碼產(chǎn)生器。把C語言程序編語言程序編譯成匯編語言程序。譯成匯編語言程序。(2匯編器:把匯編語言源代碼或匯編器:把匯編語言源代碼或C語言已經(jīng)編譯成匯編語言代碼語言已經(jīng)編譯成匯編語言代碼進(jìn)行匯編,
5、以產(chǎn)生進(jìn)行匯編,以產(chǎn)生COFF目標(biāo)文件。目標(biāo)文件。(3鏈接器:將文件鏈接,產(chǎn)生可執(zhí)行的目標(biāo)文件。鏈接器:將文件鏈接,產(chǎn)生可執(zhí)行的目標(biāo)文件。8.1.2 Shell程序程序8.1.3 C代碼優(yōu)化代碼優(yōu)化 C編譯器中含有一個(gè)編譯器中含有一個(gè)C優(yōu)化程序。啟用優(yōu)化程序。啟用C優(yōu)化程序可以提高程序執(zhí)行速優(yōu)化程序可以提高程序執(zhí)行速度,減少度,減少C程序代碼長度。對(duì)于程序代碼長度。對(duì)于C語言,可以采用簡(jiǎn)化循環(huán),使用軟件流水語言,可以采用簡(jiǎn)化循環(huán),使用軟件流水線,重新安排、語句和表達(dá)式以及將變量分配到寄存器等方法實(shí)施優(yōu)化。線,重新安排、語句和表達(dá)式以及將變量分配到寄存器等方法實(shí)施優(yōu)化。 在在CCS中,選擇菜單中
6、,選擇菜單Project/Build Options選項(xiàng),可以直接在彈出的選項(xiàng),可以直接在彈出的對(duì)話框中對(duì)優(yōu)先級(jí)別進(jìn)行設(shè)置。對(duì)話框中對(duì)優(yōu)先級(jí)別進(jìn)行設(shè)置。8.2 C程序代碼鏈接程序代碼鏈接 C編譯器和匯編語言工具為用戶鏈接程序提供了以下兩種方法。編譯器和匯編語言工具為用戶鏈接程序提供了以下兩種方法。(1先編譯各個(gè)模塊,最后將他們鏈接在一起。先編譯各個(gè)模塊,最后將他們鏈接在一起。(2一次執(zhí)行一次執(zhí)行Shell程序的程序的dspcl命令,直接完成各個(gè)模塊的編譯、匯編和鏈命令,直接完成各個(gè)模塊的編譯、匯編和鏈接。接。 在在CCS集成環(huán)境下,還有少量設(shè)置集成環(huán)境下,還有少量設(shè)置CCS環(huán)境和工程文件組織工
7、作需要環(huán)境和工程文件組織工作需要人工干預(yù)。為鏈接人工干預(yù)。為鏈接C程序,需要程序,需要DSP開發(fā)人員做以下工作:開發(fā)人員做以下工作:(1把運(yùn)行支持庫包含到工程文件中;把運(yùn)行支持庫包含到工程文件中;(2指定程序運(yùn)行時(shí)的初始化類型;指定程序運(yùn)行時(shí)的初始化類型;(3確定如何將由確定如何將由C語言程序編譯、匯編和鏈接產(chǎn)生出的可執(zhí)行代碼分配到物語言程序編譯、匯編和鏈接產(chǎn)生出的可執(zhí)行代碼分配到物理存儲(chǔ)器中。理存儲(chǔ)器中。8.2.1 把運(yùn)行支持庫包含到工程文件中把運(yùn)行支持庫包含到工程文件中 所有所有C程序都必須與運(yùn)行支持庫鏈接。因?yàn)檫\(yùn)行支持庫包含了標(biāo)準(zhǔn)程序都必須與運(yùn)行支持庫鏈接。因?yàn)檫\(yùn)行支持庫包含了標(biāo)準(zhǔn)C函函
8、數(shù),如數(shù),如sin()函數(shù),以及編譯器用來創(chuàng)建和管理函數(shù),以及編譯器用來創(chuàng)建和管理CCS中中C語言運(yùn)行環(huán)境的函數(shù)。語言運(yùn)行環(huán)境的函數(shù)。 運(yùn)行支持庫中包含了一個(gè)boot.obj目標(biāo)模塊,C程序鏈接時(shí)必須與它鏈接。當(dāng)C程序開始運(yùn)行時(shí),首先執(zhí)行boot.obj。鏈接時(shí),鏈接器會(huì)自動(dòng)提取boot.obj并鏈接它。boot.obj包含了用于初始化運(yùn)行環(huán)境的代碼和數(shù)據(jù)。該模塊執(zhí)行以下任包含了用于初始化運(yùn)行環(huán)境的代碼和數(shù)據(jù)。該模塊執(zhí)行以下任務(wù):務(wù):(1建立堆棧;建立堆棧;(2處理運(yùn)行時(shí),初始化表和自動(dòng)初始化全局變量;處理運(yùn)行時(shí),初始化表和自動(dòng)初始化全局變量;(3調(diào)用調(diào)用C語言主程序語言主程序main( );
9、(4當(dāng)當(dāng)C語言主程序語言主程序main( )結(jié)束時(shí),調(diào)用結(jié)束時(shí),調(diào)用exit( )。 boot.obj中有一個(gè)重要的匯編語言函數(shù)_c_int0。它是boot.obj中的起點(diǎn)。鏈接時(shí), _c_int0被自動(dòng)定義為程序的入口點(diǎn)。如果程序從復(fù)位開始運(yùn)行,則應(yīng)將復(fù)位向量轉(zhuǎn)移到_c_int0,以便DSP首先執(zhí)行_c_int0。8.2.2 指定初始化類型指定初始化類型 用用C語言編程時(shí),會(huì)根據(jù)需要定義全局變量和靜態(tài)變量。有些全局變量語言編程時(shí),會(huì)根據(jù)需要定義全局變量和靜態(tài)變量。有些全局變量和靜態(tài)變量具有初始值,有些全局變量和靜態(tài)變量沒有初始值。和靜態(tài)變量具有初始值,有些全局變量和靜態(tài)變量沒有初始值。C編譯
10、器對(duì)編譯器對(duì)C程序編譯后,為具有初始值的全局變量和靜態(tài)變量建立了一個(gè)專門的數(shù)據(jù)程序編譯后,為具有初始值的全局變量和靜態(tài)變量建立了一個(gè)專門的數(shù)據(jù)塊塊.cinit。該塊在程序運(yùn)行后調(diào)入到。該塊在程序運(yùn)行后調(diào)入到RAM的的.bss中。中。 .cinit調(diào)入到調(diào)入到RAM中有中有兩種方法:兩種方法:(1在運(yùn)行時(shí),自動(dòng)初始化全局變量和靜態(tài)變量;在運(yùn)行時(shí),自動(dòng)初始化全局變量和靜態(tài)變量;(2在加載時(shí),自動(dòng)初始化全局變量和靜態(tài)變量。在加載時(shí),自動(dòng)初始化全局變量和靜態(tài)變量。 當(dāng)創(chuàng)建新工程時(shí),第一種是缺省狀態(tài)。當(dāng)創(chuàng)建新工程時(shí),第一種是缺省狀態(tài)。8.2.3 把塊分配到物理存儲(chǔ)器中把塊分配到物理存儲(chǔ)器中 把塊分配到物
11、理存儲(chǔ)器中就是把程序和數(shù)據(jù)分配到物理存儲(chǔ)器中。把塊分配到物理存儲(chǔ)器中就是把程序和數(shù)據(jù)分配到物理存儲(chǔ)器中。 當(dāng)使用當(dāng)使用C編譯器對(duì)編譯器對(duì)C程序編譯后,可產(chǎn)生數(shù)據(jù)塊和代碼塊。這些塊根據(jù)程序編譯后,可產(chǎn)生數(shù)據(jù)塊和代碼塊。這些塊根據(jù)各種不同的應(yīng)用系統(tǒng)硬件配置和擴(kuò)展情況,可以使用不用的方法將這些塊分各種不同的應(yīng)用系統(tǒng)硬件配置和擴(kuò)展情況,可以使用不用的方法將這些塊分配到物理存儲(chǔ)器中。配到物理存儲(chǔ)器中。8.3 創(chuàng)建創(chuàng)建C語言軟件語言軟件8.3.1 創(chuàng)建創(chuàng)建C語言寄存器頭文件語言寄存器頭文件 與匯編語言相同,與匯編語言相同,C語言編程也需要相應(yīng)的頭文件。語言編程也需要相應(yīng)的頭文件。 2407控制寄存器數(shù)量較
12、多,為了方便編程,可以將這些寄存器地址定控制寄存器數(shù)量較多,為了方便編程,可以將這些寄存器地址定義在一個(gè)頭文件(義在一個(gè)頭文件(*.h中。這樣,在編程時(shí)只要將該文件包含其中,直接中。這樣,在編程時(shí)只要將該文件包含其中,直接引用寄存器在引用寄存器在*.h中定義的英文縮寫名,而不必記它的地址。中定義的英文縮寫名,而不必記它的地址。 在該頭文件中,寄存器是以指針方式進(jìn)行尋址。在該頭文件中,寄存器是以指針方式進(jìn)行尋址。8.3.2 創(chuàng)建創(chuàng)建main( )函數(shù)函數(shù) 在在C語言應(yīng)用軟件中,用戶必須定義一個(gè)語言應(yīng)用軟件中,用戶必須定義一個(gè)main( )函數(shù)作為自己應(yīng)用程序函數(shù)作為自己應(yīng)用程序的開始。因?yàn)橄到y(tǒng)完
13、成的開始。因?yàn)橄到y(tǒng)完成C語言環(huán)境設(shè)置后,語言環(huán)境設(shè)置后,boot.obj會(huì)自動(dòng)調(diào)用會(huì)自動(dòng)調(diào)用main( )函數(shù)函數(shù)作為程序的開始。因而,程序員在程序中編寫作為程序的開始。因而,程序員在程序中編寫main( )函數(shù)是一種預(yù)定,也函數(shù)是一種預(yù)定,也是一種強(qiáng)制。是一種強(qiáng)制。void main(void) sys_ini(); for(;) delay(); /*xf管腳置低*/ asm( clrc xf); delay(); /*xf管腳置高*/ asm( setc xf); 8.3.3 創(chuàng)建創(chuàng)建2407芯片初始化函數(shù)芯片初始化函數(shù) 初始化內(nèi)容包括:初始化內(nèi)容包括:(12407芯片初始化;芯片初始化
14、;(2工程應(yīng)用中所甬道的片內(nèi)外設(shè)初始化;工程應(yīng)用中所甬道的片內(nèi)外設(shè)初始化;(3片內(nèi)外存儲(chǔ)器初始化;片內(nèi)外存儲(chǔ)器初始化;(4應(yīng)用系統(tǒng)硬件接口初始化。應(yīng)用系統(tǒng)硬件接口初始化。#include exp4_2407.hvoid sys_ini() /系統(tǒng)初始化子程序 /*關(guān)總中斷*/ asm( setc INTM); /*抑制符號(hào)位擴(kuò)展*/ asm( clrc SXM); /*累加器中結(jié)果正常溢出*/ asm( clrc OVM); /*禁止看門狗*/ * WDCR=0 x00E8; /*CLKIN=10M,CLKOUT=40M*/ * SCSR1=0 x0000; 8.3.4 創(chuàng)建假中斷處理函數(shù)創(chuàng)建
15、假中斷處理函數(shù)(12407工作時(shí),如果意外引發(fā)了內(nèi)核級(jí)中斷,但是卻沒有低層外設(shè)中斷工作時(shí),如果意外引發(fā)了內(nèi)核級(jí)中斷,但是卻沒有低層外設(shè)中斷向量裝入外設(shè)中斷寄存器中時(shí),假中斷向量向量裝入外設(shè)中斷寄存器中時(shí),假中斷向量0000h裝入裝入PIVR;(2CPU執(zhí)行一個(gè)軟件中斷指令執(zhí)行一個(gè)軟件中斷指令I(lǐng)NTR時(shí),使用了參數(shù)時(shí),使用了參數(shù)16,企圖用軟件中,企圖用軟件中斷去服務(wù)于外設(shè)中斷斷去服務(wù)于外設(shè)中斷INT1INT6。這顯然是一個(gè)錯(cuò)誤,這時(shí),假中斷向量裝。這顯然是一個(gè)錯(cuò)誤,這時(shí),假中斷向量裝入入PIVR ;(3中斷請(qǐng)求線發(fā)生故障,外設(shè)發(fā)出中斷請(qǐng)求,而其中斷請(qǐng)求線發(fā)生故障,外設(shè)發(fā)出中斷請(qǐng)求,而其INTn
16、標(biāo)志卻在標(biāo)志卻在CPU應(yīng)應(yīng)答請(qǐng)求之前被軟件清答請(qǐng)求之前被軟件清0,此時(shí),外設(shè)中斷的請(qǐng)求可能還沒有被中斷控制器確,此時(shí),外設(shè)中斷的請(qǐng)求可能還沒有被中斷控制器確認(rèn),中斷控制器也不知道哪個(gè)外設(shè)中斷向量應(yīng)裝認(rèn),中斷控制器也不知道哪個(gè)外設(shè)中斷向量應(yīng)裝PIVR,這時(shí),假中斷向量裝這時(shí),假中斷向量裝入入PIVR .interrupt void nothing() /假中斷子程序 return; 8.3.5 _c_int0函數(shù)函數(shù) 在運(yùn)行在運(yùn)行C程序之前,用戶必須首先建立起程序之前,用戶必須首先建立起C語言運(yùn)行環(huán)境。語言運(yùn)行環(huán)境。 建立建立C語言運(yùn)行環(huán)境的函數(shù)在庫語言運(yùn)行環(huán)境的函數(shù)在庫rts2xx.lib中。
17、把中。把_c_int0函數(shù)作為硬件函數(shù)作為硬件復(fù)位后的中斷矢量入口來運(yùn)行復(fù)位后的中斷矢量入口來運(yùn)行_c_int0函數(shù)。函數(shù)。 rsvect B _c_int0 這樣,當(dāng)系統(tǒng)復(fù)位后,通過執(zhí)行一條無條件轉(zhuǎn)移指令來調(diào)用這樣,當(dāng)系統(tǒng)復(fù)位后,通過執(zhí)行一條無條件轉(zhuǎn)移指令來調(diào)用_c_int0函函數(shù),以建立數(shù),以建立C語言運(yùn)行環(huán)境。語言運(yùn)行環(huán)境。 _c_int0函數(shù)初始化函數(shù)初始化C環(huán)境時(shí)執(zhí)行了如下任務(wù):環(huán)境時(shí)執(zhí)行了如下任務(wù): (1為系統(tǒng)堆棧定義一個(gè)名為為系統(tǒng)堆棧定義一個(gè)名為.stack的塊,并建立初始化堆棧和幀指針;的塊,并建立初始化堆棧和幀指針; (2將將.cinit塊的初始化數(shù)據(jù)表中的數(shù)據(jù)復(fù)制到塊的初始
18、化數(shù)據(jù)表中的數(shù)據(jù)復(fù)制到.bss塊,對(duì)全局變量和靜態(tài)塊,對(duì)全局變量和靜態(tài)變量進(jìn)行初始化;變量進(jìn)行初始化;(3調(diào)用調(diào)用main函數(shù),開始運(yùn)行函數(shù),開始運(yùn)行C程序。程序。8.4 TMS320C240 x C語言語言8.4.1 數(shù)據(jù)類型數(shù)據(jù)類型 TMS320 x 的的C語言數(shù)據(jù)類型具有如下特征:語言數(shù)據(jù)類型具有如下特征:(1所有的整形類型,包括所有的整形類型,包括char、short和和int及其它們對(duì)應(yīng)的無符號(hào)類型,及其它們對(duì)應(yīng)的無符號(hào)類型, 是是16位二進(jìn)制數(shù),相互間是等價(jià)的。位二進(jìn)制數(shù),相互間是等價(jià)的。(2長整型和無符號(hào)長整型類型是長整型和無符號(hào)長整型類型是32位二進(jìn)制數(shù)。位二進(jìn)制數(shù)。(3帶符號(hào)
19、類型以帶符號(hào)類型以2進(jìn)制補(bǔ)碼表示。進(jìn)制補(bǔ)碼表示。(4char類型等同于類型等同于int類型,為帶符號(hào)類型。類型,為帶符號(hào)類型。(5enum類型的對(duì)象以類型的對(duì)象以16位值表示,在表達(dá)式中位值表示,在表達(dá)式中enum類型和類型和int類型等同。類型等同。(6所有浮點(diǎn)類型所有浮點(diǎn)類型float、double和和long double是等價(jià)的類型,都以是等價(jià)的類型,都以32位浮點(diǎn)格式表示。位浮點(diǎn)格式表示。(7長整型和浮點(diǎn)數(shù)保存在存儲(chǔ)器中,低位數(shù)值保存在低地址。長整型和浮點(diǎn)數(shù)保存在存儲(chǔ)器中,低位數(shù)值保存在低地址。8.4.2 C語言標(biāo)準(zhǔn)庫函數(shù)的使用語言標(biāo)準(zhǔn)庫函數(shù)的使用 TI公司的公司的C編譯器提供了編譯
20、器提供了C語言標(biāo)準(zhǔn)庫函數(shù)。它與語言標(biāo)準(zhǔn)庫函數(shù)。它與boot.asm等一起封裝等一起封裝在在rts2xx.lib中。中。 在使用標(biāo)準(zhǔn)庫函數(shù)時(shí),首先要聲明這一函數(shù)。在使用標(biāo)準(zhǔn)庫函數(shù)時(shí),首先要聲明這一函數(shù)。TI公司的所有標(biāo)準(zhǔn)庫函數(shù)公司的所有標(biāo)準(zhǔn)庫函數(shù)以分類的形式在不同的頭文件中聲明,全部聲明庫函數(shù)的頭文件為以分類的形式在不同的頭文件中聲明,全部聲明庫函數(shù)的頭文件為assert.h、limits.h、stddef.h、ctype.h 、math.h 、stdlib.h 、setjmp.h 、string.h 、stdarg.h 、time.h 、和、和ioports.h。 為了使用一個(gè)庫函數(shù),用戶必須
21、首先使用為了使用一個(gè)庫函數(shù),用戶必須首先使用#include來包含聲明函數(shù)的來包含聲明函數(shù)的頭文件。頭文件。8.5 TMS320C24x C語言程序開發(fā)語言程序開發(fā) TMS320C24x C語言具有特定的運(yùn)行環(huán)境,為了確保語言具有特定的運(yùn)行環(huán)境,為了確保C語言程序正語言程序正確運(yùn)行,確運(yùn)行,C語言程序開發(fā)必須維護(hù)這個(gè)環(huán)境。語言程序開發(fā)必須維護(hù)這個(gè)環(huán)境。8.5.1 存儲(chǔ)器模式存儲(chǔ)器模式 TMS320C24x 的的C編譯器將存儲(chǔ)器分為程序存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器。編譯器將存儲(chǔ)器分為程序存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器。程序存儲(chǔ)器包含可執(zhí)行代碼,數(shù)據(jù)存儲(chǔ)器包含外部變量、靜態(tài)變量和系程序存儲(chǔ)器包含可執(zhí)行代碼,數(shù)據(jù)存儲(chǔ)器包
22、含外部變量、靜態(tài)變量和系統(tǒng)堆棧。統(tǒng)堆棧。 由由C程序生成的每一塊代碼或數(shù)據(jù)存放于存儲(chǔ)空間的一個(gè)連續(xù)塊中。程序生成的每一塊代碼或數(shù)據(jù)存放于存儲(chǔ)空間的一個(gè)連續(xù)塊中。 存儲(chǔ)器映射及代碼和數(shù)據(jù)存儲(chǔ)空間的分配由鏈接器決定。編譯器不存儲(chǔ)器映射及代碼和數(shù)據(jù)存儲(chǔ)空間的分配由鏈接器決定。編譯器不考慮可用存儲(chǔ)空間類型,也不考慮存儲(chǔ)空間是否可以被代碼和數(shù)據(jù)使用考慮可用存儲(chǔ)空間類型,也不考慮存儲(chǔ)空間是否可以被代碼和數(shù)據(jù)使用或者存儲(chǔ)空間是否保留以用于或者存儲(chǔ)空間是否保留以用于I/O或控制。編譯器只生成可重新分配的代或控制。編譯器只生成可重新分配的代碼,鏈接器完成將代碼和數(shù)據(jù)分配到合適的存儲(chǔ)空間。碼,鏈接器完成將代碼和數(shù)
23、據(jù)分配到合適的存儲(chǔ)空間。 C匯編器對(duì)匯編器對(duì)C語言程序編譯生成語言程序編譯生成7個(gè)可以進(jìn)行重定位的代碼和數(shù)據(jù)個(gè)可以進(jìn)行重定位的代碼和數(shù)據(jù)塊:塊:.text、.cinit、.const、.switch、.bss、.stack、.sysmem。1、C編譯器生成的塊編譯器生成的塊(1).text塊包含所有可執(zhí)行代碼和浮點(diǎn)常量。塊包含所有可執(zhí)行代碼和浮點(diǎn)常量。(2).text塊包含初始化變量和常量的表。塊包含初始化變量和常量的表。(3).const塊包含字符串變量、明顯初始化的全局和靜態(tài)變量的定義和初塊包含字符串變量、明顯初始化的全局和靜態(tài)變量的定義和初始化。始化。(4).switch塊包含塊包含sw
24、itch語句表。語句表。(5).bss塊為全局和靜態(tài)變量保留空間。塊為全局和靜態(tài)變量保留空間。(6).stack塊為塊為C系統(tǒng)堆棧。系統(tǒng)堆棧。(7).sysmem塊為動(dòng)態(tài)存儲(chǔ)器分配保留空間。塊為動(dòng)態(tài)存儲(chǔ)器分配保留空間。 .text、.cinit和和.switch塊通常被鏈接到塊通常被鏈接到ROM或或RAM,必須處于程序,必須處于程序存儲(chǔ)器中;存儲(chǔ)器中;.const塊可以被鏈接到塊可以被鏈接到ROM或或RAM,但必須處于數(shù)據(jù)存儲(chǔ)器,但必須處于數(shù)據(jù)存儲(chǔ)器中;中;.bss、.stack和和.sysmem塊必須被鏈接到塊必須被鏈接到RAM,并必須處于數(shù)據(jù)存,并必須處于數(shù)據(jù)存儲(chǔ)器中。儲(chǔ)器中。 這些塊根據(jù)
25、不同的系統(tǒng)配置以不同的方式被放到存儲(chǔ)器中。鏈接這些塊根據(jù)不同的系統(tǒng)配置以不同的方式被放到存儲(chǔ)器中。鏈接器將不同模塊相同的塊組合為輸出塊。完整的程序由這些輸出塊組成,器將不同模塊相同的塊組合為輸出塊。完整的程序由這些輸出塊組成,包括匯編器的包括匯編器的.data塊。塊。2、C系統(tǒng)堆棧系統(tǒng)堆棧 C編譯器使用軟件堆棧實(shí)現(xiàn)以下功能:編譯器使用軟件堆棧實(shí)現(xiàn)以下功能:(1分配局部變量分配局部變量(2給函數(shù)傳遞參數(shù)給函數(shù)傳遞參數(shù)(3保存處理器狀態(tài)保存處理器狀態(tài)(4保存函數(shù)返回值保存函數(shù)返回值(5保存臨時(shí)變量保存臨時(shí)變量(6保存寄存器保存寄存器 堆棧運(yùn)行時(shí)從低地址向高地址增加。編譯器使用堆棧運(yùn)行時(shí)從低地址向高
26、地址增加。編譯器使用2個(gè)輔助寄存器管理個(gè)輔助寄存器管理堆棧:堆棧:(1AR1為堆棧指針為堆棧指針SP)。指向當(dāng)前堆棧頂部。)。指向當(dāng)前堆棧頂部。(2AR0為幀指針為幀指針FP)。指向當(dāng)前幀的起始處。每個(gè)函數(shù)調(diào)用會(huì)在堆)。指向當(dāng)前幀的起始處。每個(gè)函數(shù)調(diào)用會(huì)在堆棧頂創(chuàng)建一個(gè)新的幀,用于保存局部和臨時(shí)變量。棧頂創(chuàng)建一個(gè)新的幀,用于保存局部和臨時(shí)變量。 局部幀是堆棧的一個(gè)區(qū)域,用于存儲(chǔ)函數(shù)傳遞的變量和局部變量,局部幀是堆棧的一個(gè)區(qū)域,用于存儲(chǔ)函數(shù)傳遞的變量和局部變量,每一個(gè)函數(shù)調(diào)用時(shí)都要在堆棧頂部創(chuàng)建一個(gè)新的局部幀。在調(diào)用每一個(gè)函數(shù)調(diào)用時(shí)都要在堆棧頂部創(chuàng)建一個(gè)新的局部幀。在調(diào)用C函函數(shù)時(shí),數(shù)時(shí),C環(huán)境
27、會(huì)自動(dòng)管理這些寄存器,堆棧的大小由鏈接器確定。全環(huán)境會(huì)自動(dòng)管理這些寄存器,堆棧的大小由鏈接器確定。全局符號(hào)局符號(hào)_STACK_SIZE的值等于堆棧長度缺省值為的值等于堆棧長度缺省值為1KB)。)。3、動(dòng)態(tài)存儲(chǔ)空間的分配、動(dòng)態(tài)存儲(chǔ)空間的分配 編譯器運(yùn)行支持庫提供了幾個(gè)函數(shù),可以在運(yùn)行時(shí)為變量動(dòng)態(tài)地分編譯器運(yùn)行支持庫提供了幾個(gè)函數(shù),可以在運(yùn)行時(shí)為變量動(dòng)態(tài)地分配存儲(chǔ)空間,如配存儲(chǔ)空間,如malloc、calloc、realloc等。等。 動(dòng)態(tài)分配是由標(biāo)準(zhǔn)運(yùn)行支持函數(shù)提供的。動(dòng)態(tài)存儲(chǔ)空間來自定義動(dòng)態(tài)分配是由標(biāo)準(zhǔn)運(yùn)行支持函數(shù)提供的。動(dòng)態(tài)存儲(chǔ)空間來自定義在在.sysmem塊中的全局池塊中的全局池pool或
28、堆或堆heap)。)。 .sysmem塊的大小塊的大小可在鏈接時(shí)由可在鏈接時(shí)由heap選項(xiàng)設(shè)定。同樣,鏈接器也可創(chuàng)建一個(gè)名為選項(xiàng)設(shè)定。同樣,鏈接器也可創(chuàng)建一個(gè)名為_SYSMEM_SIZE的全局符號(hào),并將的全局符號(hào),并將.sysmem塊的大小符給該符號(hào)。對(duì)動(dòng)塊的大小符給該符號(hào)。對(duì)動(dòng)態(tài)分配的目標(biāo)一般通過指針對(duì)其進(jìn)行訪問,并且他們的存儲(chǔ)區(qū)被分配在一態(tài)分配的目標(biāo)一般通過指針對(duì)其進(jìn)行訪問,并且他們的存儲(chǔ)區(qū)被分配在一個(gè)獨(dú)立的段中。個(gè)獨(dú)立的段中。4、靜態(tài)和全局變量的存儲(chǔ)器分配、靜態(tài)和全局變量的存儲(chǔ)器分配 在在C程序中說明的每一個(gè)外部或靜態(tài)變量都是被分配給一個(gè)唯一的連程序中說明的每一個(gè)外部或靜態(tài)變量都是被分配
29、給一個(gè)唯一的連續(xù)空間的,空間的地址由鏈接器確定,編譯器保證這些變量的空間分配多續(xù)空間的,空間的地址由鏈接器確定,編譯器保證這些變量的空間分配多個(gè)字,以便每個(gè)變量按字邊界對(duì)準(zhǔn)。個(gè)字,以便每個(gè)變量按字邊界對(duì)準(zhǔn)。5、結(jié)構(gòu)的對(duì)準(zhǔn)、結(jié)構(gòu)的對(duì)準(zhǔn) 編譯器為結(jié)構(gòu)分配空間時(shí),它將分配足夠的字以包含所有的結(jié)構(gòu)成員。編譯器為結(jié)構(gòu)分配空間時(shí),它將分配足夠的字以包含所有的結(jié)構(gòu)成員。在一組結(jié)構(gòu)中,每個(gè)結(jié)構(gòu)開始于字邊界。在一組結(jié)構(gòu)中,每個(gè)結(jié)構(gòu)開始于字邊界。6、域的對(duì)準(zhǔn)、域的對(duì)準(zhǔn) 非域類型對(duì)準(zhǔn)于字的邊界。對(duì)域分配足夠多的位,相鄰域組裝進(jìn)一個(gè)非域類型對(duì)準(zhǔn)于字的邊界。對(duì)域分配足夠多的位,相鄰域組裝進(jìn)一個(gè)字的相鄰位,但不跨越兩個(gè)字
30、。如果一個(gè)域要跨越兩個(gè)字,則整個(gè)域?qū)⒎肿值南噜徫?,但不跨越兩個(gè)字。如果一個(gè)域要跨越兩個(gè)字,則整個(gè)域?qū)⒎峙涞较乱粋€(gè)字中。配到下一個(gè)字中。8.5.2 存儲(chǔ)器規(guī)則存儲(chǔ)器規(guī)則 TMS320C2xx編譯器嚴(yán)格規(guī)定:在編譯器嚴(yán)格規(guī)定:在C語言環(huán)境中,特殊的寄存器和特語言環(huán)境中,特殊的寄存器和特殊的操作聯(lián)系在一起。如果要將匯編語言與殊的操作聯(lián)系在一起。如果要將匯編語言與C程序接口,必須遵循對(duì)這些程序接口,必須遵循對(duì)這些寄存器的規(guī)定。寄存器的規(guī)定。 寄存器規(guī)則定義編譯器如何使用寄存器和在函數(shù)調(diào)用時(shí)如何保存值。寄存器規(guī)則定義編譯器如何使用寄存器和在函數(shù)調(diào)用時(shí)如何保存值。寄存器寄存器使用使用調(diào)用是否保存調(diào)用是否保
31、存AR0幀指針幀指針是是AR1堆棧指針堆棧指針是是AR2局部變量指針局部變量指針否否AR2AR5表達(dá)式分析表達(dá)式分析否否AR6AR7寄存器變量寄存器變量是是Accumulator表達(dá)式分析表達(dá)式分析/返回值返回值否否P表達(dá)式分析表達(dá)式分析否否T表達(dá)式分析表達(dá)式分析否否 上表列出了編譯器如何使用寄存器,并說明了在函數(shù)調(diào)用時(shí)寄存器上表列出了編譯器如何使用寄存器,并說明了在函數(shù)調(diào)用時(shí)寄存器在保存值時(shí)所起的具體作用。在保存值時(shí)所起的具體作用。域域名稱名稱預(yù)設(shè)值預(yù)設(shè)值修改修改ARP輔助寄存器指針輔助寄存器指針1是是C進(jìn)位位進(jìn)位位-是是DP數(shù)據(jù)頁指針數(shù)據(jù)頁指針-是是OV溢出位溢出位-是是OVM溢出模式溢出
32、模式-是是PM乘積移位模式乘積移位模式0否否SXM符號(hào)擴(kuò)展模式符號(hào)擴(kuò)展模式-是是TC測(cè)試控制位測(cè)試控制位-是是 上表列出了編譯器所使用的所有狀態(tài)位。預(yù)設(shè)值是編譯器在函數(shù)進(jìn)上表列出了編譯器所使用的所有狀態(tài)位。預(yù)設(shè)值是編譯器在函數(shù)進(jìn)入和返回時(shí)的期望值,修改欄是編譯器產(chǎn)生的代碼是否修改該域。入和返回時(shí)的期望值,修改欄是編譯器產(chǎn)生的代碼是否修改該域。2、堆棧指針、幀指針和局部變量指針、堆棧指針、幀指針和局部變量指針 編譯器創(chuàng)建和使用自己的軟件堆棧以用于保存函數(shù)返回地址、分配局編譯器創(chuàng)建和使用自己的軟件堆棧以用于保存函數(shù)返回地址、分配局部變量和給函數(shù)傳遞參數(shù)。當(dāng)函數(shù)需要存儲(chǔ)局部變量時(shí),可以在堆棧中創(chuàng)部變
33、量和給函數(shù)傳遞參數(shù)。當(dāng)函數(shù)需要存儲(chǔ)局部變量時(shí),可以在堆棧中創(chuàng)建自己的工作空間局部幀)。局部幀在函數(shù)入口時(shí)分配,在函數(shù)返回時(shí)建自己的工作空間局部幀)。局部幀在函數(shù)入口時(shí)分配,在函數(shù)返回時(shí)釋放。釋放。 系統(tǒng)提供堆棧指針系統(tǒng)提供堆棧指針SP)、幀指針)、幀指針FP和局部變量指針和局部變量指針LVP3個(gè)寄存器來管理堆棧和局部幀。個(gè)寄存器來管理堆棧和局部幀。 寄存器寄存器AR1用做堆棧指針。堆棧從低地址向高地址增長,用做堆棧指針。堆棧從低地址向高地址增長,SP指向堆指向堆棧中下一個(gè)可用的字。寄存器棧中下一個(gè)可用的字。寄存器AR0用做幀指針。用做幀指針。FP指向當(dāng)前函數(shù)局部幀指向當(dāng)前函數(shù)局部幀的起始地址。
34、的起始地址。PF直接指向局部幀的第一個(gè)字,該字用做臨時(shí)存儲(chǔ)單元,直接指向局部幀的第一個(gè)字,該字用做臨時(shí)存儲(chǔ)單元,可以用于實(shí)現(xiàn)寄存器到寄存器值的傳遞,同時(shí)在創(chuàng)建可重入可以用于實(shí)現(xiàn)寄存器到寄存器值的傳遞,同時(shí)在創(chuàng)建可重入C函數(shù)時(shí)也必函數(shù)時(shí)也必須使用該存儲(chǔ)單元。寄存器須使用該存儲(chǔ)單元。寄存器AR2用做局部變量指針,所有存儲(chǔ)在局部幀的用做局部變量指針,所有存儲(chǔ)在局部幀的對(duì)象包括參數(shù)都要通過對(duì)象包括參數(shù)都要通過LVP間接引用。間接引用。3、寄存器變量、寄存器變量 寄存器變量是指存儲(chǔ)于寄存器而不是寄存器變量是指存儲(chǔ)于寄存器而不是RAM的局部變量或編譯器臨時(shí)變的局部變量或編譯器臨時(shí)變量。量。(1不使用優(yōu)化器
35、不使用優(yōu)化器 不使用優(yōu)化器時(shí),編譯器至多為使用不使用優(yōu)化器時(shí),編譯器至多為使用register關(guān)鍵字的兩個(gè)變量分配寄關(guān)鍵字的兩個(gè)變量分配寄存器。變量必須在參數(shù)列表中或函數(shù)的第一塊中定義。編譯器采用存器。變量必須在參數(shù)列表中或函數(shù)的第一塊中定義。編譯器采用AR6和和AR7作寄存器變量寄存器。作寄存器變量寄存器。 AR6保存第一個(gè)變量,保存第一個(gè)變量, AR7保存第二個(gè)變量。保存第二個(gè)變量。(2使用優(yōu)化器使用優(yōu)化器 使用優(yōu)化器時(shí),所有寄存器變量定義將被忽略,由優(yōu)化器決定寄存器分使用優(yōu)化器時(shí),所有寄存器變量定義將被忽略,由優(yōu)化器決定寄存器分配。優(yōu)化器直接將變量而不是地址分配給寄存器。優(yōu)化器可以將配。
36、優(yōu)化器直接將變量而不是地址分配給寄存器。優(yōu)化器可以將AR5、AR6和和AR7用作寄存器變量。用作寄存器變量。AR5在函數(shù)調(diào)用時(shí)不保存,所以它在使用時(shí)在函數(shù)調(diào)用時(shí)不保存,所以它在使用時(shí)可以跨越多個(gè)函數(shù)使用??梢钥缭蕉鄠€(gè)函數(shù)使用。4、表達(dá)式寄存器、表達(dá)式寄存器 編譯器使用沒有用做寄存器變量的寄存器來計(jì)算表達(dá)式值和存儲(chǔ)臨時(shí)編譯器使用沒有用做寄存器變量的寄存器來計(jì)算表達(dá)式值和存儲(chǔ)臨時(shí)結(jié)果。在函數(shù)調(diào)用時(shí)不保留表達(dá)式寄存器內(nèi)容。在函數(shù)調(diào)用時(shí),用做臨時(shí)結(jié)果。在函數(shù)調(diào)用時(shí)不保留表達(dá)式寄存器內(nèi)容。在函數(shù)調(diào)用時(shí),用做臨時(shí)存儲(chǔ)的寄存器保存到局部幀,被調(diào)函數(shù)不用保存和恢復(fù)表達(dá)式寄存器。存儲(chǔ)的寄存器保存到局部幀,被調(diào)函
37、數(shù)不用保存和恢復(fù)表達(dá)式寄存器。5、返回值、返回值 如果函數(shù)返回值為標(biāo)量類型如果函數(shù)返回值為標(biāo)量類型integer、pointer或或float),則返回值保),則返回值保存在累加器中。當(dāng)返回值為存在累加器中。當(dāng)返回值為16位類型變量時(shí),返回值在累加器中符號(hào)擴(kuò)展。位類型變量時(shí),返回值在累加器中符號(hào)擴(kuò)展。8.5.3 函數(shù)結(jié)構(gòu)和調(diào)用規(guī)則函數(shù)結(jié)構(gòu)和調(diào)用規(guī)則 1、函數(shù)如何進(jìn)行調(diào)用、函數(shù)如何進(jìn)行調(diào)用 主調(diào)函數(shù)在調(diào)用另一個(gè)函數(shù)時(shí)完成以下工作主調(diào)函數(shù)在調(diào)用另一個(gè)函數(shù)時(shí)完成以下工作ARP必須為必須為AR1):):(1主調(diào)函數(shù)以逆順序?qū)?shù)壓入堆棧最右邊的參數(shù)最先壓入,最左邊的主調(diào)函數(shù)以逆順序?qū)?shù)壓入堆棧最右邊
38、的參數(shù)最先壓入,最左邊的參數(shù)最后壓入)。函數(shù)調(diào)用時(shí)最左邊的放在堆棧頂部。參數(shù)最后壓入)。函數(shù)調(diào)用時(shí)最左邊的放在堆棧頂部。(2主調(diào)函數(shù)調(diào)用被調(diào)函數(shù)。主調(diào)函數(shù)調(diào)用被調(diào)函數(shù)。(3主調(diào)函數(shù)假定在函數(shù)返回時(shí)主調(diào)函數(shù)假定在函數(shù)返回時(shí)ARP會(huì)被設(shè)定為會(huì)被設(shè)定為AR1。(4當(dāng)被調(diào)函數(shù)結(jié)束,主調(diào)函數(shù)用以下命令將參數(shù)彈出堆棧。當(dāng)被調(diào)函數(shù)結(jié)束,主調(diào)函數(shù)用以下命令將參數(shù)彈出堆棧。 SBRK n2、被調(diào)函數(shù)響應(yīng)函數(shù)入口時(shí)、被調(diào)函數(shù)響應(yīng)函數(shù)入口時(shí)ARP應(yīng)該設(shè)為應(yīng)該設(shè)為AR1,AR1用作用作SP)(1從硬件堆棧中彈出返回地址,并將其壓入軟件堆棧;從硬件堆棧中彈出返回地址,并將其壓入軟件堆棧;(2將幀指針將幀指針FP壓入軟件
39、堆棧;壓入軟件堆棧;(3分配局部幀;分配局部幀;(4如果被調(diào)函數(shù)修改如果被調(diào)函數(shù)修改AR6或或AR7,將其壓入堆棧。其他被修改的寄存器可,將其壓入堆棧。其他被修改的寄存器可以不保存;以不保存;(5執(zhí)行函數(shù)代碼;執(zhí)行函數(shù)代碼;(6如果函數(shù)返回標(biāo)量值,將返回值放入累加器。如果返回值為如果函數(shù)返回標(biāo)量值,將返回值放入累加器。如果返回值為16位整型和位整型和指針,在用累加器保存返回值時(shí)進(jìn)行正確的符號(hào)擴(kuò)展;指針,在用累加器保存返回值時(shí)進(jìn)行正確的符號(hào)擴(kuò)展;(7將將ARP改為改為AR1;(8如果保存了如果保存了AR6或或AR7,則恢復(fù),則恢復(fù)AR6或或AR7;(9釋放局部幀;釋放局部幀;(10恢復(fù)恢復(fù)FP;
40、(11將返回地址從軟件堆棧中彈出并壓入硬件堆棧;將返回地址從軟件堆棧中彈出并壓入硬件堆棧;(12返回。返回。;假定ARP=AR1POPD *+ ;將返回地址從硬件堆棧彈出,壓入軟件堆棧SAR AR0,*+;將AR0FP壓入堆棧SAR AR1,*;*SP=SPLAR AR0,#SIZE;FP=幀大小LAR AR0,*0+;FP=SP,SP+=SIZE分配局部幀空間SAR AR6,*+;AR6壓棧SAR AR7,*+;AR7壓棧;函數(shù)代碼MAR *,AR1;設(shè)置ARP=SPMAR *-;指針指向AR7LAR AR7,*-;彈出AR7LAR AR6,*-;彈出AR6SBRK SIZE+1;釋放局部幀
41、LAR AR0,*-;彈出局部幀指針FPPSHD *;將返回地址從軟件堆棧彈出,壓入硬件堆棧RET;返回8.5.4 中斷處理中斷處理 遵循中斷原則就是在不影響遵循中斷原則就是在不影響C環(huán)境的情況下實(shí)現(xiàn)中斷處理并返回環(huán)境的情況下實(shí)現(xiàn)中斷處理并返回C代碼。代碼。 c_int0為為C程序入口點(diǎn),它同時(shí)也是引導(dǎo)函數(shù),用來完成程序入口點(diǎn),它同時(shí)也是引導(dǎo)函數(shù),用來完成C環(huán)境初始化。環(huán)境初始化。在初始化工作中,沒有對(duì)中斷進(jìn)行任何處理,中斷的全部控制寄存器和狀態(tài)在初始化工作中,沒有對(duì)中斷進(jìn)行任何處理,中斷的全部控制寄存器和狀態(tài)位處于缺省狀態(tài)。在缺省狀態(tài)下,中斷沒有使能。位處于缺省狀態(tài)。在缺省狀態(tài)下,中斷沒有使
42、能。 如果系統(tǒng)中要使用中斷,用戶必須作相應(yīng)處理,使中斷使能。這些操作如果系統(tǒng)中要使用中斷,用戶必須作相應(yīng)處理,使中斷使能。這些操作很容易用很容易用asm語句實(shí)現(xiàn),或調(diào)用匯編函數(shù)來實(shí)現(xiàn),對(duì)語句實(shí)現(xiàn),或調(diào)用匯編函數(shù)來實(shí)現(xiàn),對(duì)C環(huán)境沒有影響環(huán)境沒有影響 。 調(diào)用中斷程序時(shí),首先應(yīng)調(diào)用運(yùn)行時(shí)支持庫中的子程序調(diào)用中斷程序時(shí),首先應(yīng)調(diào)用運(yùn)行時(shí)支持庫中的子程序I$SAVE。這個(gè)子程序保存了所有的寄存器。同樣,在中斷程序返回時(shí),應(yīng)調(diào)用調(diào)用這個(gè)子程序保存了所有的寄存器。同樣,在中斷程序返回時(shí),應(yīng)調(diào)用調(diào)用運(yùn)行支持庫中的子程序運(yùn)行支持庫中的子程序I $RET,用于恢復(fù)被保存的寄存器。以上過程都是,用于恢復(fù)被保存的寄
43、存器。以上過程都是自動(dòng)的,不需要用戶編程時(shí)干預(yù)。自動(dòng)的,不需要用戶編程時(shí)干預(yù)。 interrupt是是C編譯器中的中斷關(guān)鍵字,用來聲明中斷函數(shù)。格式如下:編譯器中的中斷關(guān)鍵字,用來聲明中斷函數(shù)。格式如下:interrupt void nothing() /啞中斷子程序 return; 8.6 C語言和匯編語言混合編程語言和匯編語言混合編程 用用C語言和匯編語言的混合編程方法主要有以下四種:語言和匯編語言的混合編程方法主要有以下四種:(1獨(dú)立編寫?yīng)毩⒕帉慍程序和匯編程序,分開編譯或匯編形成各自的目標(biāo)代碼模塊,程序和匯編程序,分開編譯或匯編形成各自的目標(biāo)代碼模塊,然后用鏈接器將然后用鏈接器將C程序
44、和匯編程序鏈接起來。程序和匯編程序鏈接起來。(2直接在直接在C語言程序的相應(yīng)位置嵌入?yún)R編程序。語言程序的相應(yīng)位置嵌入?yún)R編程序。(3在在C語言程序中使用匯編程序的變量。語言程序中使用匯編程序的變量。(4對(duì)對(duì)C程序進(jìn)行編譯生成相應(yīng)的匯編程序,然后對(duì)匯編程序進(jìn)行手工優(yōu)化程序進(jìn)行編譯生成相應(yīng)的匯編程序,然后對(duì)匯編程序進(jìn)行手工優(yōu)化和和修改。修改。8.6.1 獨(dú)立的獨(dú)立的C和匯編程序模塊接口和匯編程序模塊接口(1不論是用不論是用C編寫的函數(shù)還是匯編編寫的函數(shù),都必須遵守寄存器使用規(guī)編寫的函數(shù)還是匯編編寫的函數(shù),都必須遵守寄存器使用規(guī)則。則。(2必須保護(hù)必須保護(hù)C函數(shù)要用到的幾個(gè)特定寄存器。函數(shù)要用到的幾個(gè)
45、特定寄存器。(3如果要改變狀態(tài)寄存器的任何位,必須確?;謴?fù)出它們的值。如果要改變狀態(tài)寄存器的任何位,必須確?;謴?fù)出它們的值。(4中斷程序必須保護(hù)所有用到的寄存器。中斷程序必須保護(hù)所有用到的寄存器。(5從匯編程序調(diào)用從匯編程序調(diào)用C函數(shù)時(shí),以逆序方式將參數(shù)壓入堆棧,調(diào)用之后,將函數(shù)時(shí),以逆序方式將參數(shù)壓入堆棧,調(diào)用之后,將參參數(shù)彈出。數(shù)彈出。(6調(diào)用調(diào)用C函數(shù)時(shí),注意函數(shù)時(shí),注意C函數(shù)只保護(hù)了幾個(gè)特定的專用寄存器,其他寄存器函數(shù)只保護(hù)了幾個(gè)特定的專用寄存器,其他寄存器C函數(shù)可以自由使用。函數(shù)可以自由使用。(7長整型和俘點(diǎn)數(shù)在存儲(chǔ)器中存放的順序是低位字在低地址,高位字在高長整型和俘點(diǎn)數(shù)在存儲(chǔ)器中存
46、放的順序是低位字在低地址,高位字在高地址。地址。(8如果函數(shù)有返回值,返回值存放在累加器如果函數(shù)有返回值,返回值存放在累加器ACC中。中。(9匯編模塊不能改變由匯編模塊不能改變由C產(chǎn)生的產(chǎn)生的.cinit塊。塊。(10編譯器在所有的標(biāo)識(shí)符函數(shù)名、變量名等前加一下劃線編譯器在所有的標(biāo)識(shí)符函數(shù)名、變量名等前加一下劃線“_”。因。因此,編寫匯編語言程序時(shí),必須在此,編寫匯編語言程序時(shí),必須在C程序可以訪問的所有對(duì)象前加程序可以訪問的所有對(duì)象前加“_”。(11任何在匯編中定義的對(duì)象或函數(shù),如果需要在任何在匯編中定義的對(duì)象或函數(shù),如果需要在C中訪問或調(diào)用,則必須中訪問或調(diào)用,則必須用匯編指令用匯編指令.
47、global定義。同樣,如果在定義。同樣,如果在C中定義的對(duì)象或函數(shù),需要在匯編中中定義的對(duì)象或函數(shù),需要在匯編中訪問或調(diào)用,在匯編中也必須用訪問或調(diào)用,在匯編中也必須用.global定義。定義。(1C主程序:主程序:/*cmian.c*/extern int asmfunc();定義外部的匯編函數(shù);定義外部的匯編函數(shù)int gvar;定義全局變量;定義全局變量main() int i; i=asmfunc(i);調(diào)用函數(shù);調(diào)用函數(shù)(2匯編語言函數(shù)匯編語言函數(shù)_asmfunc:/*asmsub.c*/.global _asmfunc.global _gvar.text_asmfunc:POPD
48、 *+;將返回地址保存至;將返回地址保存至C堆棧堆棧SAR AR0,*+;保護(hù);保護(hù)FPSAR AR1,*;保護(hù);保護(hù)SPLAR AR0,#1;幀長度;幀長度LAR AR-,*0+,AR2;建立;建立FP和和SPLDP #_gvar;指向;指向_gvarSETC SXMLACC _gvarLAR AR2,#_3;參數(shù)偏移;參數(shù)偏移MAR *0+;指向參數(shù);指向參數(shù)ADD *,AR0;將參數(shù)加至;將參數(shù)加至gvarSACL _gvarMAR *,AR1SBRK 2LAR AR0,*-;恢復(fù)幀指針;恢復(fù)幀指針PSHD *;返回地址壓入;返回地址壓入C24x堆棧堆棧RET.end8.6.2 在在C語
49、言中直接嵌入語句語言中直接嵌入語句 是一種直接的是一種直接的C和匯編接口方法。可以在和匯編接口方法。可以在C程序中實(shí)現(xiàn)用程序中實(shí)現(xiàn)用C語言無法實(shí)語言無法實(shí)現(xiàn)的一些硬件控制功能?,F(xiàn)的一些硬件控制功能。 asm( “ 匯編語句匯編語句 ” ) 注意以下幾點(diǎn):注意以下幾點(diǎn):(1防止嵌入的防止嵌入的asm語句破壞語句破壞C環(huán)境。環(huán)境。(2在在C代碼中插入跳轉(zhuǎn)或標(biāo)號(hào)可能會(huì)影響代碼產(chǎn)生器的寄存器跟蹤算法,代碼中插入跳轉(zhuǎn)或標(biāo)號(hào)可能會(huì)影響代碼產(chǎn)生器的寄存器跟蹤算法,產(chǎn)產(chǎn)生不可預(yù)測(cè)的結(jié)果。生不可預(yù)測(cè)的結(jié)果。(3插入影響編譯環(huán)境的偽指令也可能會(huì)造成麻煩。插入影響編譯環(huán)境的偽指令也可能會(huì)造成麻煩。(4不要改變不要改
50、變C變量值,但可以讀取變量值。變量值,但可以讀取變量值。 如上,在程序中直接嵌入?yún)R編語句的典型應(yīng)用是控制芯片的一些硬件如上,在程序中直接嵌入?yún)R編語句的典型應(yīng)用是控制芯片的一些硬件資源。資源。#include exp4_2407.hvoid sys_ini() /系統(tǒng)初始化子程序系統(tǒng)初始化子程序1000 8AA0 POPD *+1001 80A0 SAR AR0,*+1002 8180 SAR AR1,*1003 B001 LAR AR0,#1h1004 00E0 LAR AR0,*0+ /*關(guān)總中斷關(guān)總中斷*/ asm( setc INTM); 1005 BE41 SETC INTM /*抑制符號(hào)位擴(kuò)展抑制符號(hào)位擴(kuò)展*/ asm( clrc SXM); 1006 BE46 CLRC SXM/*累加器中結(jié)果正常溢出累加器中結(jié)果正常溢出*/ asm( clrc OVM);1007 BE42 CLRC OVM/*禁止看門狗禁止看門狗*/*WDCR=0 x00E8; 1008 BD00 LDP #100h1009 0300 LAR AR3,0h100A B9E8 LACL #e8h100B 8B8B MAR *,AR3100C 908C SACL *,0,AR4 /*CLKIN=10M,CLKOUT=40
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 質(zhì)量控制計(jì)劃表CP
- 12、新人培訓(xùn)教材接觸
- 貸房貸委托書范本
- 敬老院雙十一活動(dòng)策劃書
- 高級(jí)文秘工作簡(jiǎn)歷模板
- 會(huì)計(jì)信息系統(tǒng)應(yīng)用 (第二版)教案全套 鐘愛軍
- 農(nóng)民合作社土地承包經(jīng)營權(quán)確權(quán)登記指南
- 三農(nóng)行業(yè)三農(nóng)村基層社區(qū)治理實(shí)踐指南
- 二零二五年辦公室防盜門定制與智能安防系統(tǒng)安裝合同
- 商務(wù)活動(dòng)策劃與執(zhí)行手冊(cè)
- 2025年企業(yè)資金授權(quán)管理協(xié)議范本
- 2024-2025學(xué)年山東省濟(jì)南市九年級(jí)(上)期末語文試卷(含答案)
- 鄧宗良《煤油燈》閱讀答案
- 2024年合理膳食教案
- 臨床檢驗(yàn)分子生物學(xué)發(fā)展
- 2025版年度城市綠化活動(dòng)策劃及實(shí)施服務(wù)合同范本
- 2025年全國高考體育單招政治時(shí)事填空練習(xí)50題(含答案)
- 人教版高中物理《圓周運(yùn)動(dòng)》
- 【課件】平行線的概念課件人教版(2024)+數(shù)學(xué)七年級(jí)下冊(cè)
- 勞務(wù)派遣服務(wù)方案(技術(shù)方案)
- 2024年醫(yī)療器械經(jīng)營質(zhì)量管理規(guī)范培訓(xùn)課件
評(píng)論
0/150
提交評(píng)論