连接文件的基础知识-PLC技术网(www.plcjs.com)-可编程控制器技术门户


连接文件的基础知识

 (点击题目可以在互联网中搜索该题目的相关内容)
日期:2007-8-21 22:05:20     来源:   作者: 点击:
点击【 大  中  小 】,可以选择字体的大小,以便你阅读.
在C应用程序项目中,连接命令文件是最重要的,在编写连接命令之前,应首先了解3个基础知识:C6000的存储器映射,C6000编译器的C环境实现和COFF文件格式以及连接器的使用。

1. 基础之一:C6000的存储映射(C6201)

    在C6000 4G地址空间内,程序和数据的存放并不是随意的。要正确合理地安排程序和数据的存放地址,就必须了解C6000的存储器地址映射。

    编译器生成的代码段一般以.text为段名,所有其他的段都可以看做是数据段

2. 基础之二:COFF文件格式和C6000编译器的C环境实现

    TI代码产生工具产生的目标文件是一种模块化的文件格式——COFF格式。程序中的代码和数据在COFF文件中是以段的形式组织。COFF文件是由头文件(File Header)、段头(Section Header)、符号表(Symbol Table)以及段数据等数据结构组成。文件中包含了段的完备信息,如段的绝对地址、段的名字、段的各种属性以及段的原始数据。

    对于C语言文件,编译器生成的代码段取名为.text.全局变量和静态变量分配在.bss段中,而一般的局部变量或是使用寄存器,或是分配在.stack段中。由于堆栈和存储器分配函数的需要,编译器所产生的目标文件中有两个段(.stack和.sysmem)专门用于为堆栈和动态分配存储器函数保留存储空间。如果用户程序没有使用malloc、calloc和realloc这样的函数,那么编译器就不会产生.sysmem段。另外,对于用关键字far定义的变量,专门分配在.bss以外的数据段.far(.bss段与.far段内的数据访问方式不一样,分配在.bss段内的数据具有较高的访问效率)。

    对于编程者,除了要熟悉这些段的名字及用途外,还要关注程序编译生成的.map文件(产生.map文件使用-m选项,在CCS选项对话框,linker页的Map Filename(-m)编辑框中输入.map文件名即可)。因为.map文件中记录了段的各种详细信息,通过观察.map文件可以知道段的地址分配是否正确。实际上,从.map文件可以分析大部分和地址相关的程序错误。

    除了上述默认的代码段和数据段,用户还可以在C程序内用#pragma CODE_SECTION或DATA_SECTION(在汇编程序内用汇编伪指令.sect或.unsect)来说明其他用户自定义的代码段和数据段。

#pragma DATA_SECTION(GlobalBuf, 'sect_sb')  //数据GlobalBul放在sect_sb段中

#pragma DATA_SECTION(GlobalBuf, 4)        //数据首地址按4字节对齐

int far GlobalBuf[2048];

#pragma CODE_SECTION(Func1,'sect_ab') //函数Func1的代码放在sect_sb段中   

void Func1(int a, int b)

{

     ……

}

3. 基础之三:连接器的使用

    连接器的输入文件是汇编器产生的浮动地址目标文件(.obj),产生的输出文件是可执行目标文件(.out)和连接过程结果说明文件(.map)。在连接过程中,连接器把所有目标文件中的同名段合并,并按照用户的连接器命令文件(.cmd)给各个段分配地址,最后生成可执行的.out文件。

    对于汇编程序,系统复位和数据初始化等都是由用户程序完成:而对于C程序或对于C语言框架的混合语言程序,系统复位和数据初始化都必须基于C的运行环境。C的运行环境包括建立堆栈,变量初始化和调用main函数等,这就是前面提到的c_int00()函数完成的任务。要得到C运行库的支持,C程序就必须和C运行库rtsxxx.lib连接,这就是前面提到的一个C程序项目至少要包含的库之一。命令行方式编译时需要用连接器选项-l说明运行支持库,在ccs中只要将库文件加入到项目中即可。

    如果选择-c选项,那么C初始化函数c_int00()会读取.cinit段中的每一个记录信息,分别初始化.bss段中的全局/静态变量,最后调用main()函数。这样,用户程序就可以直接使用这些已经初始化好的全局/静态变量。对于需要对ROM加载的程序,一般应该选择-c选项。

本新闻共2页,当前在第11 2  

上一篇: 子程序导入问题
下一: 科威PLC的妙用