一 CCS連接器的做用和過程程序員
彙編器已經將源文件(.asm)順序地按段的定義(SPC)轉換成機器語言目標文件(.obj文件),即COFF文件, 鏈接器的主要任務是根據鏈接命令或鏈接命令文件(.cmd)將一個或多個 COFF目標文件鏈接起來,生成存儲器映象文件(.map)和可執行的輸出 文件(.out文件),即COFF目標模塊。 連接過程爲:算法
(1)將各個目標文件合併起來,將各個文件的各個段配置到目標系統的存儲器中模塊化
(2)對各個符號和段進行重定位,並給它們指定一個最終的地址函數
(3)解決輸入文件之間未定義的外部引用 。ui
二 連接命令文件的寫法spa
coff(公共目標文件格式,Common object file format)文件格式是基於塊(section)的概念創建的,即程序被分解成各類塊的組合體:如文本塊、數據塊等。 具備一下特色:操作系統
(1)便於實現模塊化程序設計命令行
(2)爲管理代碼塊和目標系統存儲器提供更強有力和更加靈活的方法設計
(3)程序員設計時只需基於代碼塊和數據塊等概念進行,不需關注每條命令或每一個數據的具體目標地址。至於它們的最終將處於存儲器的哪一個位置,將由連接器來安排code
(4)爲程序編寫和移植提供了很大的方便
1 section
Section目標文件中最小單位稱爲塊。一個塊就是最終在存儲器映象中佔據連續空間的一段代碼或數據。全部的section按照是否自定義能夠分爲:
(1)Coff默認的section (2)自定義的section ,按照是否初始化能夠分爲:(1)初始化的section(2)未初始化的section 。C語言和彙編中可能有些不一樣。
彙編器中默認的section有:
section | 做用 | 一般位置 |
.text |
一般包含可執行代碼 |
RAM或者EPROM |
.data |
一般包含已初始化數據 |
ROM或者EPROM |
.bss |
一般用來爲未初始化變量保留 |
RAM |
彙編中自定義模塊能夠經過.sect 建立具可重定位地址的命名塊 和.usect創立未初始化塊。
C語言的section能夠區分以下:
section | 做用 |
.text |
可代碼和常數 |
.cinit |
變量初值表 |
.switch | 用於大型switch語句的跳轉表 |
.const |
常量和字符串 |
.bss | 全局變量和靜態變量 |
.system | 全局堆(用於存儲器的分配) |
.stack | 堆棧 |
.far | 以far聲明的全局和靜態變量 |
.cio | 用於stdio函數 |
.ebss | 長調用的.bss(超過了64K地址限制) |
.esysmem | 長調用的.sysmem(超過了64K地址限制) |
econst | 長.const(可定位到任何地方) |
固然,C語言中能夠自定義段
2.CMD
連接器有兩種定位快的辦法,一種是採用默認的分配算法,彙編中的過程以下:
(1)假定存儲器的起始地址爲0
(2)假定有2^32字的存儲器能夠用來分配
(3)將.text分配到起始地址爲0的程序存儲器中
(4)將.data分配到緊接着.text的程序存儲器中
(5)將.bss分配到緊接着.data的程序存儲器中
(6)分配自定義的section。
鏈接器也能夠經過連接命令文件來完成,CMD文件由三部分組成:
(1) 輸入輸出定義;
這一部分,能夠經過ccs的「Build Option........」菜單設置。主要包含如下幾個部分:
具體的指令有:
-a 產生絕對地址(不可從新定位)的可執行模塊,若沒有指定-a或-r,默認狀況爲-a-r 產生可從新定位不可執行的模塊-ar 產生可從新定位可執行的模塊-b 鏈接器將不合並任何因爲多個文件而可能存在的重複符號表項,此項選擇的效果是使鏈接器運行較快,但其代價是輸出的COFF文件較大-c 使用由TMS320C54x C/C++編譯器的ROM自動初始化模型所定義的鏈接約定-cr使用由C編譯器的RAM自動初始化模型所定義的鏈接約定-e global_symbol 定義全局符號爲輸出模塊的指定主入口點-f fill value爲輸出段中空洞設定默認的填充值, fill value爲16位的常數-h 使全部的全局符號爲靜態變量-g global_symbol保持指定的global_symbol爲全局符號,而無論是否使用了-h選項-help , -? 顯示全部可利用的鏈接命令行選項-head size爲C語言的動態存儲器分配設置堆棧大小,以字爲單位,並定義指定的堆棧大小的全局符號,size有默認值爲1k字-i dir 改變庫搜索方法爲在搜索默認的位置前先搜索dir ,該項必須在-l(L)選項以前出現-l filename 指定一個存檔庫文件爲鏈接器的輸入 , filename爲存檔庫文件名,該選項必須在-i 選項以後出現,目錄或文件名必須遵照操做系統的規定-m filename 產生一個存儲器(地址)映射文件,輸出名爲filename.map , 該文件列出了輸入和輸出段(包括空洞)的地址-o filename 指定可執行輸出模塊的文件名(filename) , 默認爲a.out , 目錄或文件名必須遵照操做系統的規定-q 請求靜態運行(quiet run) ,即壓縮旗標(banner)必須是在命令行的第一個選項-s 從輸出模塊中去掉符號表信息和行號-stack size 設置C系統堆棧,大小以字爲單位,並定義指定堆棧大小的全局符號,默認的size爲1k-u symbol 將不能分辯的外部符號放入輸出模塊的符號表-vn 指定產生的COFF文件格式n , n=0、1或2,默認爲COFF2-w 當出現沒有定義的輸出段時,發出警告-x 迫使重讀庫,以分辯後面的引用
MEMORY: 定義目標系統的存儲器映象,能夠給它們命名,規定起始地址和長度
用法:MEMORY { 存儲器空間名:o = 十六進制存儲器起始地址 l = 十六進制存儲器長度 }
例如:
MEMORY { L2RAM: o = 0x10800000 l = 0x00020000 DDR2: o = 0x80000000 l = 0x10000000 }
(3) SECTION命令。
SECTIONS:指定怎樣組合各輸入塊以及將各輸出塊存放在存儲器 的哪一個位置
用法:
sections { 段名1 > 存儲器空間名1 段名2 > 存儲器空間名2 . . . }
例子:
SECTIONS { .bss > L2RAM .cinit > L2RAM .cio > L2RAM .const > L2RAM .data > L2RAM .far > L2RAM .stack > L2RAM .switch > L2RAM .sysmem > L2RAM .text > L2RAM .ddr2 > DDR2 }
CMD中也能夠自定義section,用法以下:
#pragma DATA_SECTION(函數名或全局變量名,"用戶自定義在數據空間的段名");
#pragma CODE_SECTION(函數名或全局變量名,"用戶自定義在程序空間的段名");
具體用法以下:
sections { 段名1 > 存儲器空間名1 段名2 > 存儲器空間名2 }
能夠參開網址:CMD