C语言生成的段和CMD文件(精)
初学CMD文件
一、有关段(sections)的知识汇编器和链接器产生的可被DSP装置执行的目标程序,这些目标文件格式被称为通用目标文件格式(COFF)。
COFF使得模块化编程更容易,它鼓励用户在写汇编语言程序时根据代码块和数据块的方式来思考如何编写程序,这些“模块(block)”就是“段(sections)”。
目标文件的最小单位称为段,段是占据一个连续空间的代码块或数据块,与其他段一起在存储器映射图内。
目标文件的各个段是分开的,有特色的。
一个COFF目标文件总是包含3个默认段:(1).text段,通常包含可执行代码;(2).data段,通常含有初始化数据;(3).bss段,通常为未初始化变量预留的空间。
自定义的段:(1)由汇编伪指令.sect创建的段(2)由汇编伪指令.usect创建的段其中,.text、.data、由.sect创建的段属于初始化段(含有数据和代码);.bss、由.usect创建的段属于未初始化段(为未初始化的数据在存储器映像图内预留空间)。
注:不能用不同的伪指令定义相同的段。
二、由汇编器产生的COFF格式的OBJ文件中的段作为构造块,当有多个文件进行链接时,链接器会将输入段结合在一起产生可执行的COFF输出模块,然后链接器为各输出段选择存储器地址,这就是CMD文件。
CMD文件是用来分配ROM和RAM的,告诉链接程序怎么计算地址和分配空间。
它包括三个部分:(1)输入、输出定义:.obj文件——链接器要链接的目标文件;.lib文件——链接器要链接的库文件;.map文件——链接器生成的交叉索引文件;.out文件——链接器生成的可执行代码。
这部分可通过CCS中的Build Option菜单进行设置。
(2)MEMORY命令:描述系统实际的硬件资源,即指定芯片的ROM和RAM的大小和并划分出的几个区间。
默认的,PAGE0对应ROM(程序存储区),PAGE1对应RAM(数据存储区),例定义一个VECS存储区域,具有R和W属性,填充常数ffffh:MEMORY{PAGE 0:VECS(RW):origin=0000h,length=00ffh,f=ffffh;}注:1)PAGE就是对一个存储空间进行标记,最多可以有255个PAGE,每个PAGE代表一个完全独立的地址空间,不同的PAGE上的存储器区间可以取相同的名字;2)Attr:可选项,规定存储器属性:①R,可以对存储器执行读操作;②W,可以对存储器执行写操作;③X,命名的存储器能包含可执行的代码;④I,可以对存储器进行初始化;3)origin:起始地址,可写成org或o;length:长度,可写成len或l。
1·什么是cmd文件,它有什么作用。
1·什么是CMD文件,它有什么作用。
CMD文件是用来说明对应的对应的代码、数据、变量的存放空间。
它包括两个指令SECTOINS和MEMORY。
如果把RAM和ROM看成是两个仓库的话,那MEMORY指令就是把这两个仓库再分成不同的区域。
如果把不同的代码段是看成一件件货物的话,那么SECTOINS指令则指出了这些货物对应的存放位置。
.cmd文件由汇编器产生的COFF格式的OBJ文件中的段作为构造块,当有多个文件进行链接时,链接器会将输入段结全在一起产生可执行的COFF输出模块,然后链接器为各输出段选择存储器地址。
1.1 MEMORY指令说明存储器(MEMORY)伪指令,用来定义目标系统的存储器空间。
MEMORY可以定义存储器的区域,并指定起始地址和长度。
MEMORY伪指令的一般语法:MEMORY{PAGE 0: name1[(attr)]:origin=constant, length=constant;PAGE n: name1[(attr)]:origin=constant, length=constant;}PAGEn中的页号n最大为255。
每个PAGE代表一个完全独立的地址空间。
通常PAGE0为程序存储器,PAGE1为数据存储器。
Name1:存储器区间名。
可包含8个字符。
不同PAGE可以取同样的name1,但在同一个PAGE 内区间名不可以相同。
Attr:可选项。
规定存储器属性。
R,可以对存储器执行读操作W,可以对存储器执行写操作X,破除可以装入可执行的程序代码I,规定可以对存储器进行初始化Origin:起始地址。
Length:区间长度。
初始化段用SECTIONS可定位两次:装入和运行。
如:一些关键的执行代码必须装在系统的ROM中,但希望在较快的RAM中运行。
未初始化段只可被定位一次。
自己写的关于LF2406A的.cmd文件MEMORY{PAGE 0: VECS: origin=0h, length=40h ;中断向量表,40h~43h为安全代码;或保留代码区,复位向量是0h和1h FLASH: origin=44h, length=0ffbch ;32KflashSARAM: origin=8000h, length=800h ;当PON=1&&DON=0,;SARAM映射为程序存储空间B0: origin=ff00h, length=100h ; 256 WORD DARAM,CNF=1时PAGE 1: MMRS: origin=0h, length=60h ;内部映射寄存器,或保留区间B2: origin=60h, length=20h ;32 WORD DARAMB0: origin=200h, length=100h ;256 WORD DARAM,CNF=0时B1: origin=300h, length=100h ;256 WORD DARAMSARAM: origin=800h, length=800h ;2K WORD SARAM,DON=1&&PON=0PF1:origin=7000, length=230h ;外设帧1EV A: origin=7400, length=32h ;外设帧2EVB: origin=7500, length=32h ;外设帧3}内部的所有的存储器都定义过了,最后的三个PF1、EV A、EVB可以不用定义的,因为是这外设的寄存器映射。
存储器配置与CMD文件的编写
存储器配置与CMD文件的编写存储器配置与CMD文件的编写1. VC5402 的存储器配置文件文件中的注释采用 C 语言风格,即用 /* */ 可以注释一行或多行。
特别注意,不能用 // 来注释一行。
一个例子:/*filename: uxer_learn.cmd*This file is a configration file for VC5402 Program and Data Space*Last modified by Zhang Yong. */MEMORY{PAGE 0: PROG(RWXI): origin = 0x80, length = 0x3000VECS(RXI): origin = 0xff80, length = 0x80PAGE 1: DATA(RWI): origin = 0x3080, length = 0xf80}/* MEMORY 为存储器指示关键字,程序区用 PAGE 0 来表示,数据区用 PAGE 1来表示。
程序区和数据区都使用了 VC5402 片上的 64Kx16 bit 的DARAM。
程序区和数据区的名称可以按C 语言的风格任意取名。
程序区命名为PROG,占据了约 12Kx16bit 的空间;数据区命名为 DATA,占据了约 4Kx16bit的 DARAM 空间。
origin = 0x80 代表了程序空间的起始地址,length = 0x3000 代表程序空间长度为 0x3000。
*/SECTIONS{.text {} > PROG PAGE 0.cinit {} > PROG PAGE 0.pint {} > PROG PAGE 0.vectors {} > PROG PAGE 0.stack {} > DATA PAGE 1.bss {} > DATA PAGE 1.const {} > DATA PAGE 1.switch {} > DATA PAGE 1.sysmem {} > DATA PAGE 1.cio {} > DATA PAGE 1}/* SECTIONS 是存储器区段关键字;.text 等是汇编指示关键字,它的含义为将程序段放入 PAGE 0 的 PROG 区域;.cinit 指示将 C 语言初始化数据存入PROG 区域中;.pint 指示将 C++ 程序初始化数据存入 PROG 区域中;.stack表示在 PAGE 1 的 DATA 区域开辟堆栈;.bss 指示将未初始化的变量分配在DATA 区域;.const 指示将常量分配在 DATA 区域;.switch 指示将 C 语言的switch 语句分配到DATA 区域;.sysmem 指示将C 语句(如malloc 或 alloc)开辟的存储区分配到 DATA 区域。
DSP的CMD文件详解(整理版)
DSP的CMD文件详解CMD是用来分配ROM和RAM空间用的,告诉链接程序怎样计算地址和分配空间。
所以不同的芯片就有不同大小的ROM和RAM,存放用户程序的地方也不尽相同。
所以要根据芯片进行修改,分为 MEMORY 和SECTIONS两个部分。
MEMORY{PAGE 0 ..........PAGE 1.........}SECTIONS{.vectors ..................reset .................................}MEMORY是用来指定芯片的ROM和RAM的大小和划分出几个区间。
PAGE 0对应ROM, PAGE 1对应RAM。
PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。
SECTIONS:(在程序里添加下面的段名,如.vectors。
用来指定该段名以下,另一个段名以上的程序(属于PAGE0)或数据(属于PAGE1)放到“>”符号后的空间名字所在的地方。
){.vectors : { } > VECS PAGE 0.reset : { } > VECS PAGE 0..................................}eg:MEMORY{PAGE 0:VECS :origin = 00000h, length = 00040h LOW :origin = 00040h, length = 03FC0h SARAM :origin = 04000h, length = 00800h B0 :origin = 0FF00h, length = 00100h PAGE 1:B0 :origin = 00200h, length = 00100h B1 :origin = 00300h, length = 00100h B2 :origin = 00060h, length = 00020h SARAM :origin = 08000h, length = 00800h }{.text : { } > LOW PAGE 0.cinit : { } > LOW PAGE 0.switch : { } > LOW PAGE 0.const : { } > SARAM PAGE 1.data : { } > SARAM PAGE 1.bss : { } > SARAM PAGE 1.stack : { } > SARAM PAGE 1.sysmem : { } > SARAM PAGE 1}由三部分组成:①输入/输出定义:这一部分,可以通过ccs的“BuildOption........”菜单设置: .obj(链接的目标文件)、.lib(链接的库文件)、.map(生成的交叉索引文件)、.out(生成的可执行代码)。
CMD文件的设定
FLASHE
: origin = 0x3E8000, length = 0x004000
FLASHD
: origin = 0x3EC000, length = 0x004000
FLASHC
: origin = 0x3F0000, length = 0x004000
FLASHA
: origin = 0x3F6000, length = 0x001F80
}
Code 放在 FlashA;
我们可以修改 cmd 文件;如我们把 FLASHC-J 当作一个 FLASH,即
FLASHJ
: origin = 0x3D8000, length = 0x018000 /* on-chip FLASHC-J */
当然 CECTIONS 段里要把
IQmath
: > FLASHC
CMD 文件的设定
以.CMD 为扩展名的文件,这个文件的作用是用来分配存储空间的。由于 DSP 编译器 的编译结果是未定位的,DSP 也没有操作系统来定位执行代码,DSP 系统的配置需求也不 尽相同,因此我们根据实际的需求,自己定义代码的存储位置。打个通俗的比喻,就是我们 有一个仓库,现在需要把货物存放到仓库里面去,为了便于日后取用货物,我们将货物分门 别类,然后把它们存放到指定的位置去。把哪些货物放到哪个位置的规则,就是我们的 CMD 文件的内容。
PAGE = 0
.reset
: > RESET,
PAGE = 0, TYPE = DSECT /* not used, */
.stack
: > RAMM1,
PAGE = 1
.ebss
: > DRAMH0,
CC++学习----使用C语言代替cmd命令、cmd命令大全
CC++学习----使⽤C语⾔代替cmd命令、cmd命令⼤全【开发环境】物理机版本:Win 7 旗舰版(64位)IDE版本:Visual Studio 2013简体中⽂旗舰版(cn_visual_studio_ultimate_2013_with_update_4_x86_dvd_5935081_Chinese-Simplified)【前⾔】cmd常⽤命令:calc:启动计算器notepad:打开记事本netstat -a:查看所有的端⼝tasklist:查看所有的进程d: 盘符切换dir(directory) 列出当前⽬录下的⽂件以及⽂件夹md (make directory) 创建⽬录rd (remove directory) 删除⽬录(带内容的⽂件或者⽂件夹不能直接删除,必须先删除⾥⾯,再删除外⾯)。
如果要删除⾮空⽬录,可以使⽤命令:rd /s xxxdir或者rd /s /q xxxdircd (change directory) 改变指定⽬录(进⼊指定⽬录)cd.. 退回到上⼀级⽬录cd\ 退回到根⽬录del (delete) 删除⽂件,删除⼀堆后缀名⼀样的⽂件*.txtexit 退出dos命令⾏cls (clear screen)清屏Win7中打开cmd窗⼝的⽅式:在当前路径下,按住shift键,⿏标右键:⼀、通过C语⾔代码来实现cmd命令⾏功能:这⾥⽤到了c语⾔中的⼀个库:#include<stdlib.h>1、打开记事本:cmd.cpp:#include<stdlib.h>void main() {system("notepad"); //System:执⾏系统的命令⾏}程序⼀运⾏,记事本就打开了:2、查看ip地址:#include<stdlib.h>void main(){system("ipconfig");system("pause"); //如果没有这⼀⾏代码,cmd窗⼝就会闪退}注:如果没有第04⾏的pause,cmd窗⼝就会闪退。
使用C语言操作SCI寄存器与CMD文件的编写
[cpp] view plaincopy
SciaRegs.SCICCR.all = 0x0007;
对 SCIHBAUD 和 SCILBAUD 进行操作
[cpp] view plaincopy
SciaRegs.SCIHBAUD = 0; SciaRegs.SCILBAUD = 0xF3;
六.寄存器文件的空间分配(CMD 文件的产生)
值得注意的是,之前所做的工作只是将 F2812 的寄存器按照 C 语言中位域定义和寄存器结构体的方式组织了数据结构,当编译时, 编译器会把这些变量分配到存储空间中,但是很显然还有一个问题需 要解决,就是如何将这些代表寄存器数据的变量同实实在意的是之前所做的工作只是将f2812的寄存器按照c语言中位域定义和寄存器结构体的方式组织了数据结构当编译时编译器会把这些变量分配到存储空间中但是很显然还有一个问题需要解决就是如何将这些代表寄存器数据的变量同实实在在的物理寄存器结合起来
使用 C 语言操作 SCI 寄存器与 CMD 文件的编写
13. };
14.
15. extern volatile struct SCI_REGS SciaRegs;
16. extern volatile struct SCI_REGS ScibRegs;
定义为 union 形式的成员既可以实现对寄存器整体的操作,也可以实
现对寄存器位的操作。
定义为 Uint16 形式的成员只能直接对寄存器进行操作
对 SCICCR 按位进行操作[cpp] view plaincopy
SciaRegs.SCICCR.bit.STOPBITS = 0; SciaRegs.SCICCR.bit.PARITYENA = 0; SciaRegs.SCICCR.bit.LOOPBKENA = 0; SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0; SciaRegs.SCICCR.bit.SCICHAR = 7;
CMD文件
第二章CMD文件2.1、CMD文件综述CMD文件的主要作用是沟通物理存储器和逻辑地址的桥梁。
CMD文件反映了实际电路中存储单元的大小,并且通过阅读CMD文件可以得到系统中存储器的分配情况,特别是配合以MAP文件就可非常方便地得到系统资源的使用情况,有利于优化系统配置。
另外,由于C28X推荐使用C语言编程,就存在程序转化分段的问题,也在CMD中得到落实。
本实验系统采用的是瑞泰的CMD程序,并且是针对一个实验系统的通用CMD文件。
2.2、例解CMD文件1、寄存器区// 片上外设寄存器结构体与存储器分配的对应关系MEMORY //反映存储器空间范围、描述系统实际的硬件资源{PAGE 0: //第0页:程序空间存储器PAGE 1: //第1页:地址空间存储器//芯片仿真设定用寄存器(始于0x0000880 长:0x000180)DEV_EMU : origin = 0x000880, length = 0x000180//中断向量表PIE_VECT : origin = 0x000D00, length = 0x000100//闪存寄存器组FLASH_REGS : origin = 0x000A80, length = 0x000060//保密位寄存器组CSM : origin = 0x000AE0, length = 0x000010// 外部扩展寄存器组XINTF : origin = 0x000B20, length = 0x000020//定时器0 寄存器组CPU_TIMER0 : origin = 0x000C00, length = 0x000008//PIE控制寄存器组PIE_CTRL : origin = 0x000CE0, length = 0x000020 ///增强型CAN模块寄存器组ECANA : origin = 0x006000, length = 0x000040ECANA_LAM : origin = 0x006040, length = 0x000040ECANA_MOTS : origin = 0x006080, length = 0x000040 ECANA_MOTO : origin = 0x0060C0, length = 0x000040ECANA_MBOX : origin = 0x006100, length = 0x000100//系统控制寄存器组SYSTEM : origin = 0x007010, length = 0x000020//外设接口寄存器组SPIA : origin = 0x007040, length = 0x000010//异步串行通信接口寄存器组SCIA : origin = 0x007050, length = 0x000010//外部中断设定寄存器组XINTRUPT : origin = 0x007070, length = 0x000010//多功复用引脚选择寄存器组GPIOMUX : origin = 0x0070C0, length = 0x000020//多功能引脚数据寄存器组GPIODAT : origin = 0x0070E0, length = 0x000020//模拟数字转换寄存器组ADC : origin = 0x007100, length = 0x000020// 事件管理寄存器组EV A : origin = 0x007400, length = 0x000040EVB : origin = 0x007500, length = 0x000040//异步串行通信接口B寄存器组SCIB : origin = 0x007750, length = 0x000010//多通道缓冲接口寄存器组MCBSPA : origin = 0x007800, length = 0x000040//密码保护寄存器组CSM_PWL : origin = 0x3F7FF8, length = 0x000008}SECTIONS //建立与程序一一对应的关系、描述段是如何定位{PieVectTableFile : > PIE_VECT, PAGE = 1/*** Peripheral Frame 0 Register Structures ***///在头文件中可以找到DevEmuRegsFile的定义DevEmuRegsFile : > DEV_EMU, PAGE = 1FlashRegsFile : > FLASH_REGS, PAGE = 1CsmRegsFile : > CSM, PAGE = 1XintfRegsFile : > XINTF, PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1PieCtrlRegsFile : > PIE_CTRL, PAGE = 1/*** Peripheral Frame 1 Register Structures ***/SysCtrlRegsFile : > SYSTEM, PAGE = 1SpiaRegsFile : > SPIA, PAGE = 1SciaRegsFile : > SCIA, PAGE = 1XIntruptRegsFile : > XINTRUPT, PAGE = 1GpioMuxRegsFile : > GPIOMUX, PAGE = 1GpioDataRegsFile : > GPIODAT PAGE = 1AdcRegsFile : > ADC, PAGE = 1EvaRegsFile : > EV A, PAGE = 1EvbRegsFile : > EVB, PAGE = 1ScibRegsFile : > SCIB, PAGE = 1McbspaRegsFile : > MCBSPA, PAGE = 1/*** Peripheral Frame 2 Register Structures ***/ECanaRegsFile : > ECANA, PAGE = 1ECanaLAMRegsFile : > ECANA_LAM PAGE = 1ECanaMboxesFile : > ECANA_MBOX PAGE = 1ECanaMOTSRegsFile : > ECANA_MOTS PAGE = 1ECanaMOTORegsFile : > ECANA_MOTO PAGE = 1/*** Code Security Module Register Structures ***/CsmPwlFile : > CSM_PWL, PAGE = 1}2、程序区/*// FILE: F2812_EzDSP_RAM_lnk.cmd//定位C程序在存储器中的位置-l rts2800.lib //链接库文件rts2800.lib-w //-stack 400h //栈大小为400h-heap 100 //堆大小为100MEMORY{PAGE 0 :///RAMM0 : origin = 0x000000, length = 0x000400//RAMM0 : origin = 0x3f6000, length = 0x001000BEGIN : origin = 0x3F8000, length = 0x000002/*BEGIN : origin = 0x3F7FF6, length = 0x000002*///PRAMH0 : origin = 0x3f8002, length = 0x001000PRAMH0 : origin = 0x81000, length = 0x002000RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM (MP/MCn=0) or XINTF zone 7 (MP/MCn=1) */VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM (MP/MCn=0) or XINTF zone 7 (MP/MCn=1) */PAGE 1 :/* For this example, H0 is split between PAGE 0 and PAGE 1 */RAMM1 : origin = 0x000400, length = 0x000400DRAMH0 : origin = 0x3f8002, length = 0x001ffcDRAMH1 : origin = 0x83000, length = 0x004ffc}SECTIONS{codestart : > BEGIN, PAGE = 0//ramfuncs : > PRAMH0 PAGE = 0.text : > PRAMH0, PAGE = 0//文本段.cinit : > PRAMH0, PAGE = 0//.pinit : > PRAMH0, PAGE = 0.switch : > PRAMH0, PAGE = 0.reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */ .stack : > RAMM1, PAGE = 1.ebss : > DRAMH1, PAGE = 1.econst : > DRAMH0, PAGE = 1.esysmem : > DRAMH0, PAGE = 1.const : > DRAMH0, PAGE = 1.sysmem : > DRAMH0, PAGE = 1.cio : > DRAMH0, PAGE = 1}1..cinit 存放C程序中的变量初值和常量2..const 存放C程序中的字符常量、浮点常量和用const声明的常量3..text 存放C程序的代码4..bss 为C程序中的全局和静态变量保留存储空间5..far 为C程序中用far声明的全局和静态变量保留空间6..stack 为C程序系统堆栈保留存储空间,用于保存返回地址、函数间的参数传递、存储局部变量和保存中间结果7..sysmem用于C程序中malloc、calloc和realloc函数动态分配存配空间2.3文件类型.pjt CCS使用的工程文件.c C程序源文件.asm 汇编程序源文件.h 头文件.lib 库文件.cmd 连接命令文件.obj 目标文件.out 可执行文件.wks 工作区文件.dat 数据文件.map 映射文件2.4、常用命令。
使用C语言操作SPI的寄存器及相应的CMD文件
使用C语言操作SPI的寄存器及相应的CMD文件1.SPI寄存器结构体文件定义:struct SPI_REGS{union SPICCR_REG SPICCR; // 配置控制寄存器定义union SPICTL_REG SPICTL; //工作控制寄存器定义union SPISTS_REG SPISTS; // 状态寄存器定义Uint16 rsvd1; // 保留位Uint16 SPIBRR; // 波特率寄存器定义Uint16 rsvd2; // 保留位Uint16 SPIRXEMU; //仿真缓冲寄存器定义Uint16 SPIRXBUF; //串行接收缓冲寄存器定义Uint16 SPITXBUF; //串行发送缓冲寄存器定义Uint16 SPIDAT; // 串行数据寄存器定义union SPIFFTX_REG SPIFFTX; // FIFO发送寄存器定义union SPIFFRX_REG SPIFFRX; // FIFO接收寄存器定义union SPIFFCT_REG SPIFFCT; // FIFO控制寄存器定义Uint16 rsvd3[2]; //保留位union SPIPRI_REG SPIPRI; // FIFO优先级控制寄存器定义};extern volatile struct SPI_REGS SpiaRegs;extern volatile struct SPI_REGS SpibRegs;2.使用DATA_SECTION方法将寄存器文件分配到数据空间# pragma DATA_SECTION(SpiaRegs,”SpiaRegsFile”);volatile struct SPI_REGS SpiaRegs;# pragma DATA_SECTION(SpibRegs,”SpibRegsFile”);volatile struct SPI_REGS SpibRegs;3.将数据段映射到寄存器对应的存储空间(.CMD)MEMORY{PAGE 1:SPIA : origin = 0x007040, length = 0x000010 /* SPIA寄存器*/ SPIB : origin = 0x007740, length = 0x000010 /* SPIB寄存器*/ }SECTIONS{SpiaRegsFile : > SPIA, PAGE = 1SpibRegsFile : > SPIB, PAGE = 1}。
[原]TMS320F28335项目开发记录6_28335之cmd文件详解
[原]TMS320F28335项目开发记录6_28335之cmd文件详解2014-11-3阅读970 评论01.CMD文件的作用CMD文件的作用就像仓库的货物摆放记录一样,为程序代码和数据分配指定的空间。
2.C语言生成的段C语言生成的段大致分为两大类:初始化和未初始化,已初始化的段含有真正的指令和数据,未初始化段只是保留变量的地址空间。
已初始化段通常放在程序空间,未初始化段通常放在数据空间。
已初始化段:.text——C语言编译生成的汇编指令代码存放于此.cinit——存放初始化的全局和静态变量.const——字符串常量和const定义的全局和静态变量.econst——字符串常量和far const定义的全局和静态变量.print——全局构造器(C++)程序列表.switch——存放switch语句产生的常数表格以.const段为例:const int a = 10; //注意必须是全局的如果声明为局部const初始化变量,不会放在.const段,局部变量都是运行时放在.bss段中char * p = "ABC";数组和结构体的初始值——是局部变量时,产生的是.const,如果是全局变量,产生的是.cinit未初始化段:.bss——为全局变量和局部变量保留的空间,程序上电时,.cinit空间中的数据复制出来并存放在.bss空间中.ebss——为使用大寄存器模式时预留的全局和局部变量空间,程序上电时,.cinit空间中的数据复制出来并存放在.bss空间中.stack——堆栈空间,主要用于函数传递变量或为局部变量分配空间.system——为动态存储分配保留的空间(malloc),如果有宏函数,此空间被占用.esystem——为动态存储分配保留的空间(far malloc),如果有far函数,此空间会被占用3.自定义段上面的都是官方预先定义好的,我们可以定义自己的段么?可以,使用如下语句:#pragma CODE_SECTION(symbol, "section name");#pragma DATA_SECTION(symbol, "section name");symbol——符号,可以是函数名/变量名section name——自定义的段名CODE_SECTION用来定义代码段DATA_SECTION用来定义数据段注意:不能再函数体内声明#pragma;必须在符号被定义和使用之前声明#pragma例子:#pragma DATA_SECTION(data, "data_name");char data[100];4.CMD文件在DSP28335工程文件里(不用BIOS产生CMD文件),手写CMD文件一般有两个,RAM里调试时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd 和28335_RAM_lnk.cmd,烧写到flash里时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和F28335.cmd,其中DSP2833x_Headers_nonBIOS.cmd文件可以在所有工程文件中通用,主要作用是把外设寄存器产生的数据段映射到对应的存储空间,可以跟DSP2833x_GlobalVariableDefs.c文件对照一下看看。
C语言生成的段和CMD文件
C语言生成的段和CMD文件通用目标文件格式COFF(Common Object File Format),是一种很流行的二进制可执行文件格式。
二进制可执行文件包括库文件(以后缀.lib结尾)、目标文件(以后缀.obj结尾)、最终的可执行文件(以后缀.out结尾)等。
1. COFF格式详细的COFF文件格式包括段头、可执行代码和初始化数据、可重定位信息、行号入口、符号表、字符串表等,这些属于编写操作系统和编译器人员关心的范畴。
从应用的层面上讲,DSP的C语言程序员应掌握两点:通过伪指令定义段;并给段分配空间。
至于二进制文件到底如何组织分配,则交由编译器完成。
把握COFF格式的概念,最关键的一点就是:二进制可执行文件是以段(section)的形式存储的。
使用段的好处是鼓励模块化编程,提供更强大而又灵活的方法来管理代码和目标系统的内存空间。
这里模块化编程的意思是,程序员可以自由决定愿意把哪些代码归属到哪些段,然后加以不同的处理。
编译器处理段的过程为:每个源文件都编译成独立的目标文件(以后缀.obj 结尾),每个目标文件含有自己的段,连接器把这些目标文件中相同段名的部分连接在一起,生成最终的可执行文件(以后缀.out结尾)。
段分为两大类:已初始化的段和未初始化的段。
已初始化的段含有真实的指令和数据,存放在程序存储空间。
程序存储空间在DSP片内的FLASH。
调试代码时,则常常把代码在线下载到RAM中运行。
未初始化的段只是保留变量的地址空间,未初始化的段存放在数据存储空间中,数据存储空间多为RAM存储单元。
在DSP上电调用_c_int0初始化库前,未初始化的段并没有真实的内容。
汇编语言中,通过六条伪指令来定义段,因此时常把伪指令和段混为一谈,比如伪指令“.bss”,也是段“.bss”。
(1)未初始化的段1).bss:定义变量存放空间。
2).usect:用户可自行定义未初始化的段,提供给用户更多的灵活性。
(2)已初始化的段1).text:包含可执行的汇编指令代码。
程序开发工具及CMD文件课件
管理CMD文件
将CMD文件纳入版本控制系统中,可以方便地追 踪文件的修改历史、协同工作以及恢复旧版本等操 作。
团队协作
通过版本控制系统,团队成员可以共同管 理CMD文件,实现高效的团队协作。
PART 04
CMD文件在项目开发中 的应用
自动化部署
自动化部署
CMD文件可以用于自动化部署应用程 序和软件,通过编写批处理命令,可 以一键完成安装、配置和启动等操作 ,提高部署效率。
程序开发工具与CMD文 件的结合应用
使用IDE创建和管理CMD文件
01
集成开发环境(IDE )
IDE是一种集成了代码编辑、编译、 调试等多种功能的软件,可以方便地 创建和管理CMD文件。常见的IDE有 Visual Studio、Eclipse等。
02
创建CMD文件
03
管理CMD文件
在IDE中,可以直接创建CMD文件, 并为其命名。CMD文件通常用于存储 命令行指令,以便在命令行界面中执 行。
系统环境配置
系统环境变量
CMD文件可以用于设置和修改系统环境变量,以便在应用程序运行时获取正确的路径 和参数。
系统服务管理
CMD文件可以用于管理系统的服务,例如启动、停止、重启等,方便对系统服务的维 护和管理。
PART 05
CMD文件常见问题及解 决方案
CMD文件执行权限问题
权限不足
CMD文件在执行时可能会因为权 限不足而无法正常打开或运行。 这通常是因为文件所有者、权限 设置或安全软件限制等原因造成 的。
IDE提供了强大的文件管理功能,可 以方便地对CMD文件进行编辑、保存 、删除等操作。同时,IDE还可以对 CMD文件进行版本控制,方便团队协 作。
c语言程序中内存的划分及各个段的含义
c语言程序中内存的划分及各个段的含义【C语言程序中内存的划分及各个段的含义】1. 引言C语言是一种广泛应用在系统编程和嵌入式开发中的高级编程语言,其灵活性和效率使得它成为了众多开发者的首选。
在C语言程序中,内存的划分及各个段的含义是一个至关重要的话题。
本文将从简单到复杂,由浅入深地探讨这一主题。
2. 内存的基本划分在C语言程序中,内存主要被划分为四个部分:- 代码段:也称为文本段,用来存储程序的代码。
- 数据段:用来存储全局变量和静态变量。
- 栈:用来存储局部变量和函数的参数。
- 堆:用来动态分配内存。
3. 代码段代码段是存储程序执行代码的地方。
在程序执行之前,代码段被加载到内存中,并且通常是只读的,以防止程序意外修改其内容。
在代码段中,指令被存储为机器可执行的二进制代码,并且按照程序的控制流顺序执行。
4. 数据段数据段用来存储全局变量和静态变量。
全局变量是在函数外部定义的变量,它在程序的整个执行过程中都是可见的。
而静态变量则是在函数内部使用关键字static声明的变量,它的生命周期与程序的执行时间相同,但是只能在定义它的函数中可见。
5. 栈栈用来存储局部变量和函数的参数。
每当一个函数被调用时,栈上就会分配一段内存空间,用来存储该函数的参数和局部变量。
当函数执行完毕后,该段内存空间就会被释放,以便其他函数使用。
6. 堆堆是用来动态分配内存的地方。
在程序执行过程中,有时需要动态地分配内存空间,以存储一些临时数据或者动态创建一些对象。
C语言提供了一些标准的库函数,如malloc和free,用来在堆上进行内存的分配和释放。
7. 内存管理在C语言程序中,内存管理是一个非常重要的问题。
由于C语言不提供自动内存管理机制(如Java中的垃圾回收),因此程序员需要自行负责内存的分配和释放。
这就需要程序员在编写程序时尽可能地小心谨慎,以免出现内存泄漏或者内存溢出的情况。
8. 结论在本文中,我们从简单到复杂地探讨了C语言程序中内存的划分及各个段的含义。
cmd文件的编写
DSP的存储器的地址范围,CMD是主要是根据那个来编的。
CM D 它是用来分配RO M和RAM空间用的,告诉链接程序怎样计算地址和分配空间.所以不同的芯片就有不同大小的ROM和RAM.放用户程序的地方也不尽相同.所以要根据芯片进行修改.分两部分.MEMORY和S ECTIONS.M EMORY{PA GE 0..........PAGE 1.........}SECTION S{SECTIO NS{.vect ors ..................rese t .................................}MEMO RY是用来指定芯片的R OM和RAM的大小和划分出几个区间.PAGE 0 对应R OM PAGE1对应RAMPA GE里包含的区间名字与其后面的参数反映了该区间的起始地址和长度.SE CTIONS:(在程序里添加下面的段名如.vector s.用来指定该段名以下,另一个段名以上的程序(属于PA GE0)或数据(属于PA GE1)放到“>”符号后的空间名字所在的地方。
SECTIO NS{.vect or s : { }> VECS PAG E 0.reset : { } >V ECS PAGE0..................................}eg:MEMORY{PAGE 0:VECS :ori gin = 00000h, length = 00040hLOW :or igi n = 00040h, len gth = 03F C0hSA RAM :origi n= 04000h, length = 00800hB0 :origin= 0FF00h,l ength = 00100hP AGE1:B0 :ori gin= 00200h, length= 00100hB1 :origin = 00300h, length =00100hB2:origin =00060h, le ngth= 00020hSARAM:or igin =08000h, len gth = 00800h}SECT IONS{.te xt : { }> LOW PA GE0.cin it : { }> LOW PAG E 0.s wit ch : {}> LOW PAG E 0.cons t : { } >SARAM PAGE 1.data: { } >SAR AM PAG E 1.bss: { } > S ARAM P AGE 1.sta ck : { } >SARAM PAG E 1.sysme m : { } >SARAM PA GE 1}由三部分组成:输入/输出定义:这一部分,可以通过ccs的“Build Op tion........”菜单设置.obj 链接的目标文件.lib 链接的库文件.map生成的交叉索引文件.out 生成的可执行代码M EMOR Y命令:描述系统实际的硬件资源SECT ION命令:描述“段”如何定位例子.c md文件-c-o hello.ou t-m hello.map-st ac k 100-l r ts2xx.libMEMOR Y{P AGE0: VEC T:o rigin=0x8000,lengt h 0x040P AGE 0: PRO G:origin=0x8040,le ng th 0x6000PAGE 1: DA TA:or igin=0x8000,len gth 0x400}SECTIONS{.vextor s >VECT PA GE 0.text >PROG P AG E 0.bs s >DATAP AGE1.co nst >DA TA PAGE1}存储模型:c程序的代码和数据如何定位系统定义.c init 存放程序中的变量初值和常量.const 存放程序中的字符常量、浮点常量和用con st声明的常量.switc h 存放程序中swi tch语句的跳转地址表.text 存放程序代码.bss为程序中的全局和静态变量保留存储空间.far 为程序中用f ar声明的全局和静态变量保留空间.st ack 为程序系统堆栈保留存储空间,用于保存返回地址、函数间的参数传递、存储局部变量和保存中间结果.sysmem 用于程序中的malloc、calloc、和realoc函数动态分配存储空间C MD 的专业名称叫链接器配置文件,是存放链接器的配置信息的,我们简称为命令文件,其中比较关键的就是M EMORY和SECT IONS两个伪指令的使用,常常令人困惑,系统出现的问题也经常与它们的不当使用有关。
CMD文件编写
F2812的CMD文件的编写CMD文件里包含三部分内容:1)输入/输出定义:.obj文件:链接器要链接的目标文件;.lib文件:链接器要链接的库文件;.map文件:链接器生成的交叉索引文件;.out文件:链接器生成的可执行代码;链接器选项2)MEMORY命令:描述系统实际的硬件资源3)SECTIONS命令:描述“段”如何定位F2812的CMD文件只包含后两部分,现对它的编写做一下总结:(一)用于调试时用,取名为SRAM.CMD(二)用于烧写到FLASH中时用,取名为FLASH.CMDFLASH.CMD与SRAM.CMD基本一样,只是有两处改动:一是MEMORY中将你的程序代码部分映射到FLASH空间里;二是在SECTIONS中添加一个用户定义的起始段,起始段的代码如下://User Defined Sections , Used by file DSP28_CodeStartBranch.asmcodestart : > BEGIN, PAGE = 0其中DSP28_CodeStartBranch.asm中的关键代码为:.ref _c_int00.sect “codestart”Code_start:LB _c_int00.end这里有个比较标准的F2812的CMD文件,可以供大家借鉴使用:MEMORY{sPAGE 0:ZONE0 : origin = 0x002000, length = 0x002000ZONE1 : origin = 0x004000, length = 0x002000RAML0 : origin = 0x008000, length = 0x001000ZONE2 : origin = 0x080000, length = 0x080000ZONE6 : origin = 0x100000, length = 0x080000OTP: origin = 0x3D7800, length = 0x000800FLASHJ : origin = 0x3D8000, length = 0x002000FLASHI : origin = 0x3DA000, length = 0x002000FLASHH : origin = 0x3DC000, length = 0x004000FLASHG : origin = 0x3E0000, length = 0x004000FLASHF : origin = 0x3E4000, length = 0x004000FLASHE : origin = 0x3E8000, length = 0x004000FLASHD : origin = 0x3EC000, length = 0x004000FLASHC : origin = 0x3F0000, length = 0x004000 FLASHA: origin = 0x3F6000, length = 0x002000 BEGIN_H0 : origin = 0x3F8000, length = 0x000002 BEGIN_FLASH : origin = 0x3F7FF6, length = 0x000002 PRAMH0 : origin = 0x3F8002, length = 0x001FFE ZONE7 : origin = 0x3FC000, length = 0x003FC0 ROM : origin = 0x3FF000, length = 0x000FC0 RESET : origin = 0x3FFFC0, length = 0x000002 VECTORS : origin = 0x3FFFC2, length = 0x00003E PAGE 1 :R AMM0 : origin = 0x000000, length = 0x000400 RAMM1 : origin = 0x000400, length = 0x000400DEV_EMU : origin = 0x000880, length = 0x000180 FLASH_REGS : origin = 0x000A80, length = 0x000060 CSM : origin = 0x000AE0, length = 0x000010XINTF : origin = 0x000B20, length = 0x000020 CPU_TIMER0 : origin = 0x000C00, length = 0x000008 CPU_TIMER1 : origin = 0x000C08, length = 0x000008 CPU_TIMER2 : origin = 0x000C10, length = 0x000008 PIE_CTRL : origin = 0x000CE0, length = 0x000020 PIE_VECT : origin = 0x000D00, length = 0x000100 ECAN_A: origin = 0x006000, length = 0x000100 ECAN_AMBOX : origin = 0x006100, length = 0x000100SYSTEM : origin = 0x007010, length = 0x000020 SPI_A: origin = 0x007040, length = 0x000010SCI_A: origin = 0x007050, length = 0x000010 XINTRUPT : origin = 0x007070, length = 0x000010 GPIOMUX : origin = 0x0070C0, length = 0x000020 GPIODA T : origin = 0x0070E0, length = 0x000020 ADC : origin = 0x007100, length = 0x000020EV_A: origin = 0x007400, length = 0x000040EV_B : origin = 0x007500, length = 0x000040SCI_B : origin = 0x007750, length = 0x000010 MCBSP_A: origin = 0x007800, length = 0x000040RAML1 : origin = 0x009000, length = 0x001000 FLASHB : origin = 0x3F4000, length = 0x002000 CSM_PWL : origin = 0x3F7FF8, length = 0x000008 DRAMH0 : origin = 0x3f9000, length = 0x001000}SECTIONS{.text : > PRAMH0, PAGE = 0 包括所有的可执行代码和常数.cinit : > PRAMH0, PAGE = 0 包括初始化的变量和常量表.stack : > RAMM1, PAGE = 1.buss : > RAMM0, PAGE = 1.ebss : > RAMM0, PAGE = 1.const : > RAMM0, PAGE = 1.econst : > RAMM0, PAGE = 1.sysmem : > RAMM1, PAGE = 1.reset : > RESET, PAGE = 0, TYPE = DSECT // 复位中断向量表//Peripheral Frame 0 Register StructuresDevEmuRegsFile : > DEV_EMU, PAGE = 1FlashRegsFile : > FLASH_REGS, PAGE = 1CsmRegsFile : > CSM, PAGE = 1XintfRegsFile : > XINTF, PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1PieCtrlRegsFile : > PIE_CTRL, PAGE = 1PieV ectTable : > PIE_VECT, PAGE = 1//Peripheral Frame 1 Register StructuresSysCtrlRegsFile : > SYSTEM, PAGE = 1SpiaRegsFile : > SPI_A, PAGE = 1SciaRegsFile : > SCI_A, PAGE = 1XIntruptRegsFile : > XINTRUPT, PAGE = 1GpioMuxRegsFile : > GPIOMUX, PAGE = 1GpioDataRegsFile : > GPIODA T PAGE = 1AdcRegsFile : > ADC, PAGE = 1EvaRegsFile : > EV_A, PAGE = 1EvbRegsFile : > EV_B, PAGE = 1ScibRegsFile : > SCI_B, PAGE = 1McbspaRegsFile : > MCBSP_A, PAGE = 1//Peripheral Frame 2 Register StructuresECanaRegsFile : > ECAN_A, PAGE = 1ECanaMboxesFile : > ECAN_AMBOX PAGE = 1//Code Security Password LocationsCsmPwlFile : > CSM_PWL, PAGE = 1}(三)SECTIONS中段的含义与用户自定义段的方法1、各个段的含义此外还有一些段的含义如下(这仅是我见过的,有漏下的还请提示,大家一起学习):.reset 复位中断向量表.vectors 中断向量表.data 已初始化数据,常数数据(比如对变量的初始化数据).pvecs 外围模块中断向量表.ref 引用外部定义的变量或函数名.global 引用全局变量或函数.space 定义要保留的空间.def 定义变量,与#define功能相同.end 段的结束标识.sect 用户自定义的已初始化段.asect 比.sect多了绝对地址定位功能,一般不用.usect 用户自定义的未初始化段已初始化的段:.text, .cinit, .const, .econst, .pinit, .switch.text:所有可以执行的代码和常量.cinit:全局变量和静态变量的C初始化记录.const:包含字符串常量和初始化的全局变量和静态变量(由const)的初始化和说明.econst:包含字符串常量和初始化的全局变量和静态变量(由far const)的初始化和说明.pinit:全局构造器(C++)程序列表.switch:包含转换语气声明的列表非初始化的段:.bss, .ebss, .stack, .sysmem, .esysmem(更好的理解就是,这些段就是存储空间而已)..bss:为全局变量和局部变量保留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.bss空间中.ebss:为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.ebss中.stack:为系统堆栈保留的空间,主要用于和函数传递变量或为局部变量分配空间.sysmem:为动态存储分配保留的空间。
c语言源程序经过编译程序编译后所产生的文件扩展名
c语言源程序经过编译程序编译后所产生的文件扩展名在撰写这篇文章之前,让我们首先来深入探讨一下C语言源程序经过编译程序编译后所产生的文件扩展名。
C语言作为一种高级程序设计语言,其源代码需要通过编译器进行编译后才能生成可执行文件。
而在编译过程中,会产生一些特定的文件扩展名,我们将从简到繁地来讨论这个主题。
1. .c源文件我们需要了解的是C语言源程序文件的扩展名为.c。
在编写C语言程序时,我们通常将源代码保存为以.c为后缀的文件,比如hello.c、main.c等。
这些.c文件包含了完整的C语言代码,需要通过编译器将其转换为机器语言才能执行。
2. .obj目标文件在进行编译时,编译器会将.c文件编译生成目标文件,其文件扩展名通常为.obj。
目标文件是编译器输出的中间文件,包含了编译后的机器语言代码和一些符号表等信息,但还不能直接作为可执行文件运行。
3. .exe可执行文件经过连接器的处理,将目标文件连接生成可执行文件,其文件扩展名为.exe。
可执行文件包含了机器语言代码和连接器生成的一些其他信息,可以直接在操作系统中执行,完成程序的运行。
4. .o目标文件和.a库文件在Unix/Linux系统中,编译生成的目标文件通常以.o为扩展名,而库文件通常以.a为扩展名。
这与Windows系统的.obj和.exe略有不同,但本质相同,都是编译和连接生成的文件。
5. 综述C语言源程序经过编译程序编译后所产生的文件扩展名包括.c、.obj (.o)、.exe以及.a等。
这些文件扩展名代表了C语言程序经过编译、连接等阶段生成的不同类型文件,对于我们理解程序编译过程及调试程序都有着重要的意义。
6. 个人观点和理解个人认为,了解C语言源程序编译后所产生的文件扩展名是非常重要的,这有助于我们深入理解程序编译连接的过程,也有助于我们更好地进行程序调试和优化。
对于想要深入学习C语言的初学者来说,掌握这些知识也是基础中的基础。
通过本文的讨论,希望读者能对C语言源程序编译后所产生的文件扩展名有更深入的理解,从而在编程学习和实践中能够更加得心应手。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C 语言生成的段和CMD 文件通用目标文件格式COFF (Common Object File Format), 是一种很流行的二进制可执行文件格式。
二进制可执行文件包括库文件(以后缀.lib 结尾)、目标文件(以后缀.obj 结尾)、最终的可执行文件(以后缀.out 结尾)等。
1. COFF格式详细的COFF 文件格式包括段头、可执行代码和初始化数据、可重定位信息、行号入口、符号表、字符串表等,这些属于编写操作系统和编译器人员关心的范畴。
从应用的层面上讲,DSP 的C 语言程序员应掌握两点:通过伪指令定义段;并给段分配空间。
至于二进制文件到底如何组织分配,则交由编译器完成。
把握COFF 格式的概念,最关键的一点就是:二进制可执行文件是以段(section )的形式存储的。
使用段的好处是鼓励模块化编程,提供更强大而又灵活的方法来管理代码和目标系统的内存空间。
这里模块化编程的意思是,程序员可以自由决定愿意把哪些代码归属到哪些段,然后加以不同的处理。
编译器处理段的过程为:每个源文件都编译成独立的目标文件(以后缀.obj 结尾),每个目标文件含有自己的段,连接器把这些目标文件中相同段名的部分连接在一起,生成最终的可执行文件(以后缀.out 结尾)。
段分为两大类:已初始化的段和未初始化的段。
已初始化的段含有真实的指令和数据,存放在程序存储空间。
程序存储空间在DSP 片内的FLASH 。
调试代码时,则常常把代码在线下载到RAM 中运行。
未初始化的段只是保留变量的地址空间,未初始化的段存放在数据存储空间中,数据存储空间多为RAM 存储单元。
在DSP 上电调用_c_int0初始化库前,未初始化的段并没有真实的内容。
汇编语言中,通过六条伪指令来定义段,因此时常把伪指令和段混为一谈,比如伪指令“.bss ”,也是段“.bss ”。
(1未初始化的段1 .bss :定义变量存放空间。
2 .usect :用户可自行定义未初始化的段,提供给用户更多的灵活性。
(2已初始化的段1.text :包含可执行的汇编指令代码。
.text 是系统定义的默认段,如果不明确声明,代码就归属.text 段。
2.data :一般包括常数数据。
比如,用来对变量初始化的数据或一个正弦表格等。
3.sect :用户可自行定已初始化的段,提供给用户更多的灵活性。
4.asect :作用类似于.sect ,但是多了绝对地址定位功能。
由于地址定位功能常用功能更强大又灵活的命令文件来完成,这条指令在汇编编程中已经废弃不用。
2.C 语言生成的段先解释一下堆栈的概念,二者是不同的概念。
栈(stack是由系统自动管理的一片内存,用来存放局部变量和函数压栈出栈的状态量。
进入C 语言函数时需要保存一些寄存器的状态,即压栈操作;退出函数时要还原那些寄存器,即出栈操作。
堆(heap是当用户想要自己能独立灵活地控制一些内存时,可以用malloc(等函数开辟一些动态内存区,这些动态内存区称为堆。
C 语言在运行时并不检查堆栈溢出与否。
如果堆栈段定义在数据存储空间的最后区域,实际运行时即使堆栈发生溢出,也不会覆盖其他有用的数据,此时堆栈可用的最高限额是实际数据存储空间的最高地址。
C 语言有7个定义好的段,没有了汇编语言中的.data 段,以下分类叙述。
(1已初始化的段1.text :编译C 语言中的语句时,生成的汇编指令代码存放于此。
2.cinit :存放用来对全局和静态变量初始化的常量3.switch :存放switch 语句产生的常数表格。
(2未初始化的段1.bss :存放全局和静态变量。
2.stack :存放C 语言的栈。
3.sysmen :存放C 语言的堆。
4.const :稍微有些复杂的段。
简单而言,是用来存放一些特殊的常数和字符等。
#pragma是标准C 中保留的预处理命令。
程序员可以通过#pragma来定义自己的段,这是预处理命令#pragma的主要用法。
#pragma的语法是:#pragma CODE_SECTION(symbol,”section name”;#pragma DATA_SECTION(symbol,”section name”;说明:1symbol 是符号,可以是函数名也可以是全局变量名,section name是用户自己定义的段名。
2CODE_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=constantPAGE 0:name n[(attr]:origin=constant,length=constant}(1PAGE 用来标示存储空间的关键字。
page n的最大值为page 225。
C24XX 和C28XX 系列中用的是page 0、page 1,其中page 0为程序存储空间,page 1为数据存储空间。
(2name 代表某一属性和地址范围的存储空间名称。
名称可以是1-8个字符,在同一个页内名称不能相同,不同页内名称能相同。
(3attr 用来规定存储空间的属性。
共有4个属性,分别用4个字母代表:只读R 、只写W 、该空间可包含可执行代码X 、该空间可以被初始化I 。
实际使用时,简化起见,常忽略此选项,这样存储空间就能具有所有的属性。
(4orgin 用来定义存储空间起始地址的关键字。
(5length 用来定义存储空间长度的关键字。
〈2〉通过SECTIONS 伪指令来分配段到存储空间相对于简单的伪指令MEMORY ,伪指令SECTION 稍稍有些复杂。
SECTION 伪指令语法如下:SECTIONS{name :[property,property ,property ,…]name :[property,property ,property ,…]……}(1name 输出段的名称。
(2property 输出段的属性。
常用的有下面一些属性。
1load :定义输出段将会被装载到哪里的关键字。
其语法如下:load=allocation或allocation 或>allocationallocation 可以是强制地址,比如“load=0x100”。
但更多的时候,allocation 是存储空间的名称,这也是最为通常的用法。
2run :定义输出段将会在哪里运行的关键字。
其语法如下:run=allocation 或run >allocationCMD 文件规定当只出现一个关键字load 或run 时,表示load 地址和run 地址是重叠的。
实际应用中,大部分段的load 地址和run 地址是重叠的,除了.const 段。
3 输入段。
其语法如下:{input_sections}花括号“{}”中是输入段。
这里是输入段与输出段做一个区分:每一个汇编或C 语言文件经过编译会生成若干个段,多个汇编或C 语言文件生成的段大都是同名的,常见的如前面已经介绍过的段.cinit ,.bss 等等。
这些段都是输入段。
这些归属于不同文件的输入段,在CMD 文件的指示下,会被连接器连接在一起生成输出段。
4 其余的特性。
CMD 文件中还可以直接写各种编译命令。
有些程序员也喜欢这么做,考虑到读者遇见时不致于困惑,兹举几例如下:1-l rts2xx.lib /*连接系统库文件rts2xx.lib*/2-o roam.out /*最终生成的二进制文件命名为roam.out*/3-m roam.map /*生成映射文件roam.map*/4-stack 0x200 /*堆栈定为512字*/4.复杂的.const 段C 语言有中有三种情况会产生.const 段:(1关键字const 由关键字const 限定的带有全局基本变量的初始化值,比如“const int a=90;”。
但由于关键字const 限定的局部基本变量的初始化值,不会产生.const 段,局部变量都是运行时开辟在.bss 段中的。
(2字符串常数字符串常数出现在表达式中,比如,“strcpy(s,”abc ”; ”。
字符串常数用来初始化指针变量,比如“char *p=”abc ”; ”。
但当字符串常数用来初始化数组变量时,不论是全局还是局部数组变量,都不会产生.const 段,此时字符串常数生成的是.cinit 段。
比如“char s[4]=”abc ”; ”。
(3数组和结构体的初始值数组和结构体是局部变量,其初始化值会产生.const 段,比如“int a[8]={1,2,3};”。
但当数组和结构体是全局变量时,其初始化值不会产生.const 段,此时生成的是.cinit 段。
设置.const 段是基于灵活性考虑的,程序中常会有大量的常数占用数据空间,比如液晶显示用的点阵字库等。
这些数据空间存放常数值,只被用来读,而从不会被写入。
把这些常数单独编译成.const 段,就为C 编译器来做特定处理提供了条件。
那怎么存储这些常数呢?一种解决的方法是把.const 段中的常数存储在程序空间,上电时把这些常数由程序空间搬移到数据空间,但这样的初始化费时,且占用了大量的程序空间。
理想的解决方法是把.const 段中的常数固化或烧写到外在的一个ROM 或FLASH 中,并把ROM 或FLASH 的地址译码到DSP 的数据空间,这样就能避免地一种解决方法的缺陷了。
但是,当没有这个ROM 或FLASH 来存储常数时,还是要用第一种解决方法。
把.const 段从page0搬移到page1, 需要在两个地方作些设置和改动。
1 在CMD 文件中的设置在CMD 文件需要把装载和运行分开,装载在page0,运行在page1。
2 修改连接的rts2xx.lib 库在DOS 命令环境下,从trs.src 源文件库中释放出boot.asm 。
Dspar –x rts.src boot asm打开boot.asm 把里面的CONST_COPY常数改成1(原先是0)。