C语言生成的段和CMD文件
C语言生成的段和CMD文件
通用目标文件格式COFF(Common Object File Format),是一种很流行的二进制可执行文件格式。二进制可执行文件包括库文件(以后缀.lib结尾)、目标文件(以后缀.obj结尾)、最终的可执行文件(以后缀.out结尾)等。
COFF格式
详细的COFF文件格式包括段头、可执行代码和初始化数据、可重定位信息、行号入口、符号表、字符串表等,这些属于编写操作系统和编译器人员关心的范畴。从应用的层面上讲,DSP的C语言程序员应掌握两点:通过伪指令定义段;并给段分配空间。至于二进制文件到底如何组织分配,则交由编译器完成。
把握COFF格式的概念,最关键的一点就是:二进制可执行文件是以段(section)的形式存储的。
使用段的好处是鼓励模块化编程,提供更强大而又灵活的方法来管理代码和目标系统的内存空间。这里模块化编程的意思是,程序员可以自由决定愿意把哪些代码归属到哪些段,然后加以不同的处理。
编译器处理段的过程为:每个源文件都编译成独立的目标文件(以后缀.obj结尾),每个目标文件含有自己的段,连接器把这些目标文件中相同段名的部分连接在一起,生成最终的可执行文件(以后缀.out结尾)。
段分为两大类:已初始化的段和未初始化的段。
已初始化的段含有真实的指令和数据,存放在程序存储空间。程序存储空间在DSP片内的FLASH。调试代码时,则常常把代码在线下载到RAM中运行。
未初始化的段只是保留变量的地址空间,未初始化的段存放在数据存储空间中,数据存储空间多为RAM存储单元。在DSP上电调用_c_int0初始化库前,未初始化的段并没有真实的内容。
汇编语言中,通过六条伪指令来定义段,因此时常把伪指令和段混为一谈,比如伪指令“.bss”,也是段“.bss”。
(1)未初始化的段
1).bss:定义变量存放空间。
2).usect:).text:”section name”);
#pragma DATA_SECTION(symbol,”section name”);
说明:
1)symbol是符号,可以是函数名也可以是全局变量名,section name是用户自己定义的段名。
2)CODE_SECTION用来定义代码段,DATA_SECTION用来定义数据段。
使用#pragma需要注意:
1)不能在函数体内声明#pragma.
2)必须在符号被定义和使用前使用#pragma。
如果没有用到某些段,比如很多人都没有用到.sysmen段,就可以不用在CMD文件中为其分配空间。当然保险起见,也可以不论用到与否,都全分配空间,没有用到段的空间大小当然是零。
在CMD文件中,page0代表程序空间,page1代表数据空间,下表列出这些段应该分配的存储空间。
3.连接命令文件(CMD文件)
连接命令文件(Linker Command Files),以后缀.cmd结尾,简称为CMD文件。
CMD文件的两大主要功能是指示存储空间和分配段到存储空间,以下分别叙述。
〈1〉通过MEMORY伪指令来指示存储空间
MEMORY伪指令语法如下:
MEMORY
{
PAGE 0:name 0[(attr)]:origin=constant,length=constant
PAGE 0:name n[(attr)]:origin=constant,length=constant
}
(1)PAGE 用来标示存储空间的关键字。page n的最大值为page 225。C24XX和C28XX系列中用的是page 0、page 1,其中page 0为程序存储空间,page 1为数据存储空间。
(2)name 代表某一属性和地址范围的存储空间名称。名称可以是1-8个字符,在同一个页内名称不能相同,不同页内名称能相同。
(3)attr 用来规定存储空间的属性。共有4个属性,分别用4个字母代表:只读R、只写W、该空间可包含可执行代码X、该空间可以被初始化I。实际使用时,简化起见,常忽略此选项,这样存储空间就能具有所有的属性。
(4)orgin 用来定义存储空间起始地址的关键字。
(5)length 用来定义存储空间长度的关键字。
〈2〉通过SECTIONS伪指令来分配段到存储空间
相对于简单的伪指令MEMORY,伪指令SECTION稍稍有些复杂。SECTION伪指令语法如下:
SECTIONS
{
name:[property,property,property,…]
name:[property,property,property,…]
……
}
(1)name 输出段的名称。
(2)property 输出段的属性。常用的有下面一些属性。
1)load:定义输出段将会被装载到哪里的关键字。其