DSP編程技巧之13-揭開編譯器神秘面紗之鏈接器的基本選項(xiàng)
在我們對DSP編程的時(shí)候,相信沒有人會(huì)把所有的代碼都放在同一個(gè)源文件里面:光各種寄存器的初始化代碼就有幾百上千行了,再加上我們自己書寫的代碼,想想假如一個(gè).c文件里面有一萬行,該如何管理、調(diào)試呢?所以要按照功能、寄存器分類等進(jìn)行劃分,這樣一個(gè)工程就包含了很多的頭文件、源程序等等,每個(gè)源程序經(jīng)過編譯、匯編之后都會(huì)產(chǎn)生單獨(dú)的目標(biāo)文件。因?yàn)閷τ诔绦虻娜魏我稽c(diǎn)修改,都需要編譯器進(jìn)行編譯,如果每次都把所有的程序進(jìn)行重新編譯的話,是對時(shí)間和資源的極大浪費(fèi):特別是那些基于Eclipse的編譯環(huán)境,因?yàn)榛贘ava這樣的技術(shù),本身就很慢,如果一次編譯的文件很多,編譯過程是非常痛苦的等待,甚至經(jīng)常懷疑編譯環(huán)境是不是已經(jīng)掛掉了?所以為了提高效率,我們可以使用增量編譯技術(shù)只對有修改的文件進(jìn)行重新編譯和匯編,而沒有修改的則不需要更新目標(biāo)文件。但是因?yàn)?strong>編譯器和匯編器對每個(gè)源文件是單獨(dú)匯編的,它們并不知道某個(gè)模塊中的數(shù)據(jù)和程序相對于另一個(gè)模塊而言,具體位置在哪里,所以接下來我們就需要使用鏈接器把所有的目標(biāo)文件給“拼接”起來,最終生成一個(gè)可以獨(dú)立運(yùn)行的文件,即可執(zhí)行文件。它的功能包括三個(gè)主要的步驟:
(1)將代碼和數(shù)據(jù)放入“假想”中的內(nèi)存:鏈接器基于.cmd文件中對存儲(chǔ)器地址的劃分,按照不同的段把代碼和數(shù)據(jù)分別裝入對應(yīng)的地址中;當(dāng)然這完全是在電腦上完成的,不需要實(shí)際的DSP和RAM“出面”。
(2)為數(shù)據(jù)和指令分配內(nèi)存地址:最簡單的例子,為函數(shù)中斷的入口制定一個(gè)地址,這樣在進(jìn)中斷的時(shí)候,程序指針直接跳轉(zhuǎn)到中斷入口的地址就行了。
(3)修改內(nèi)部和外部的引用:鏈接器使用每個(gè)目標(biāo)文件中的重定位信息和符號表,來解析某個(gè)目標(biāo)文件中未定義的符號,因?yàn)樗锌赡苁窃趧e的目標(biāo)文件中定義的。
為了更好地理解鏈接器的行為,我們就需要了解一下它的配置選項(xiàng)。鏈接器的配置選項(xiàng)也很多,但是和程序優(yōu)化的那些選項(xiàng)相比,其含義要更容易理解一些。表1是鏈接器的最基本選項(xiàng),定義了鏈接器正常工作所必須的參數(shù)。
鏈接器的文件搜索選項(xiàng)則是鏈接器用來尋找文件時(shí)使用的,例如查找某個(gè)和FPU運(yùn)行有關(guān)的浮點(diǎn)庫函數(shù),如表2所示。