zoukankan      html  css  js  c++  java
  • CCS 的链接器

    一 CCS链接器的作用和过程

    汇编器已经将源文件(.asm)顺序地按段的定义(SPC)转换成机器语言目标文件(.obj文件),即COFF文件, 连接器的主要任务是根据连接命令或连接命令文件(.cmd)将一个或多个 COFF目标文件连接起来,生成存储器映象文件(.map)和可执行的输出 文件(.out文件),即COFF目标模块。 链接过程为:

    (1)将各个目标文件合并起来,将各个文件的各个段配置到目标系统的存储器中

    (2)对各个符号和段进行重定位,并给它们指定一个最终的地址

    (3)解决输入文件之间未定义的外部引用 。

    二 链接命令文件的写法

    coff(公共目标文件格式,Common object file format)文件格式是基于块(section)的概念建立的,即程序被分解成各种块的组合体:如文本块、数据块等。 具有一下特点:

    (1)便于实现模块化程序设计

    (2)为管理代码块和目标系统存储器提供更强有力和更加灵活的方法

    (3)程序员设计时只需基于代码块和数据块等概念进行,不需关注每条命令或每个数据的具体目标地址。至于它们的最终将处于存储器的哪个位置,将由链接器来安排

    (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........”菜单设置。主要包含以下几个部分:

    1

    具体的指令有:

    -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 迫使重读库,以分辩后面的引用
    
    (2) MEMORY命令;

    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

     
  • 相关阅读:
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    迷宫问题 POJ 3984
    UVA 820 Internet Bandwidth (因特网带宽)(最大流)
    UVA 1001 Say Cheese(奶酪里的老鼠)(flod)
    UVA 11105 Semiprime Hnumbers(H半素数)
    UVA 557 Burger(汉堡)(dp+概率)
  • 原文地址:https://www.cnblogs.com/zsb517/p/2578381.html
Copyright © 2011-2022 走看看