第 5章 TMS320C54x软件开发
? 5.1 软件开发过程及开发工具
? 5.2 公共目标文件格式
? 5.3 常用汇编伪指令
? 5.4 链接器命令文件的编写与使用
? 5.5 汇编语言程序编写方法
? 5.6 TMS320C54x C语言编程
? 5.7 用 C语言和汇编语言混合编程
5.1 软件开发过程及开发工具
1,建立源程序
2,C编译器 ( C Compiler)
3,汇编器 ( Assembler)
4,连接器 ( Linker)
5,调试工具
6.十六进制转换公用程序( Hex Conversion Utility)
返回首页
图 5-1 TMS320C54x DSP软件开发流程
表 5-1 TMS320C54xV3.50版代码
生成工具程序
返回本节
5.2 公共目标文件格式
? 5.2.1 COFF文件的基本单元 ——段
? 5.2.2 汇编器对段的处理
? 5.2.3 链接器对段的处理
? 5.2.4 重新定位
? 5.2.5 程序装入
? 5.2.6 COFF文件中的符号
返回首页
5.2.1 COFF文件的基本单元 ——段
? 段 ( sections) 是 COFF文件中最重要的概念 。
一个段就是最终在存储器映象中占据连续空间的
一个数据或代码块 。 目标文件中的每一个段都是
相互独立的 。 一般地, COFF目标文件包含 3个缺
省的段,text段, data段, bss段 。
? 段可以分为两大类,即已初始化段和未初始化段。
如图 5-2所示为目标文件中的段与目标系统中存储
器的关系。
图 5-2 目标文件中的段与目标存储器的关系
返回本节
5.2.2 汇编器对段的处理
1,未初始化段
? 未初始化段主要用来在存储器中保留空间, 通常将它们定
位到 RAM中 。 这些段在目标文件中没有实际内容, 只是
保留空间而已 。 程序可以在运行时利用这些空间建立和存
储变量 。 未初始化段是通过使用,bss和,usect汇编伪指令
建立的, 两条伪指令的句法分别为:
.bss 符号, 字数
符号,usect“段名,, 字数
2,已初始化段
? 已初始化段包含可执行代码或已初始化数据 。 这
些段的内容存储在目标文件中, 加载程序时再放
到 TMS320C54X存储器中 。 三个用于建立初始化
段的伪指令句法分别为:
.text [段起点 ]
.data [段起点 ]
.sect,段名, [,段起点 ]
3,命名段
? 命名段就是程序员自己定义的段,它与缺省
的,text,.data和,bss段一样使用,但与缺省段分
开汇编。 data段不同的存储器中,将未初始化的
变量汇编到与,bss段不同的存储器中。产生命
名段的伪指令为:
符号,usect,段名,, 字数
.sect,段名, [,段起点 ]
4,子段
? 子段 ( Subsections) 是大段中的小段 。 链接器
可以像处理段一样处理子段 。 采用子段可以使存
储器图更加紧密 。 子段的命名句法为:
基段名:子段名
? 子段也有两种, 用,sect命令建立的是已初始化段,
用,usect命令建立的是未初始化段 。
5,段程序计数器 ( SPC)
? 汇编器为每个段安排一个独立的程序计数器,即
段程序计数器( SPC)。 SPC表示一个程序代码
段或数据段内的当前地址。开始时,汇编器将每
个 SPC置 0,当汇编器将程序代码或数据加到一
个段内时,相应的 SPC增加。如果汇编器再次遇
到相同段名的段,继续汇编至相应的段,且相应
的 SPC在先前的基础上继续增加。
图 5-3 例 5-1产生的目标代码 返回本节
5.2.3 链接器对段的处理
? 链接器对段的处理有两个功能 。 首先, 它将汇编
器产生的 COFF目标文件 (,obj文件 ) 中的各种段
作为输入段, 当有多个文件进行链接时, 它将输
入段组合起来, 在可执行的 COFF输出模块中建
立各个输出段 。 其次, 链接器为输出段选择存储
器地址 。
? 链接器有两个命令完成上述功能, 即:
? MEMORY 命令 ——定义目标系统的存储器配置
图, 包括对存储器各部分的命名, 以及规定它们
的起始地址和长度 。
? SECTIONS命令 ——告诉链接器如何将输入段组
合成输出段,以及在存储器何处存放输出段。子
段可以用来更精确地编排段,可用链接器
SECTIONS命令指定子段。
图 5-4 链接器默认的存储器分配
返回本节
5.2.4 重新定位
1,链接时 重新定位
? 将各个段定位到存储器中, 每个段都从合适的地
址开始 。
? 将符号值调整到相对于新的段地址的数值 。
? 调整对重新定位后符号的引用 。
2,运行时重新定位
? 将代码装入存储器的一个地方, 而运行在另一个
地方 。 利用 SECTIONS命令选项让链接器定位两
次 。 一些关键的执行代码必须装入在系统的 ROM
中, 但希望在较快的 RAM中运行 。
? 链接器提供了一个简单的处理该问题的方法 。 利
用 SECTIONS命令选项让链接器定位两次 。 第一
次使用装入关键字设置装入地址, 再用运行关键
字设置运行地址 。
返回本节
5.2.5 程序装入
( 1) 硬件仿真器和 CCS集成开发环境, 具有内部
的装入器, 调用装入器的 LOAD命令即可装入可
执行程序 。
( 2) 将代码固化在片外存储器中, 采用 Hex转换工
具 ( Hex conversion utility), 例如 Hex500将
可执行的 COFF目标模块 (,out文件 ) 转换成几
种其他目标格式文件, 然后将转换后的文件用编
程器将代码写入 EPROM/Flash。
返回本节
5.2.6 COFF文件中的符号
? COFF文件中有一个符号表, 用于存储程序中的
符号信息 。 链 接器对符号重定位时使用该表, 调
试工具也使用该表来提供符号调试 。
? 外部符号指在一个模块中定义, 在另一个模块中
使用的符号 。 可使用,def,.ref或,global汇编伪
指令将符号定义为外部符号 。,def在当前模块中
定义, 可以在别的模块中使用的符号;,ref在当
前 模 块 中 引 用, 但 在 别 的 模 块 中 定 义 的 符
号;,global可用于以上任何一种情况 。
返回本节
5.3 常用汇编伪指令
返回首页
表 5-2 常用的汇编 伪指令
1,段定义伪指令
? 为便于链接器将程序, 数据分段定位于指定的 ( 物理存在
的 ) 存储器空间, 并将不同的 obj文件链接起来 。 段的使
用非常灵活, 但常用以下约定:
?,text — 此段存放程序代码 。
?,data — 此段存放初始化了的数据 。
?,bss — 此段存入未初始化的变量 。
?,sect '名称 ' — 定义一个有名段, 放初始化了的数据或程
序代码 。
2,条件汇编伪指令
?,if,.elseif,.else,.endif伪指令告诉汇编器按照表达式
的计算结果对代码块进行条件汇编 。
?,if expression — 标志条件块的开始, 仅当条件为真
( expression的值非 0即为真 ) 时汇编代码 。
?,elseif expression — 标志若,if条件为假, 而,elseif条件
为真时要汇编代码块 。
?,else — 标志若,if条件为假时要汇编代码块 。
?,endif — 标志条件块的结束, 并终止该条件代码块 。
3,引用其他文件和初始化常数伪指令
?,include '文件名 ' — 将指定文件复制到当前位置, 其内
容可以是程序, 数据, 符号定义等 。
?,copy '文件名 ' — 与,include类似 。
?,def 符号名 — 在当前文件中定义一个符号, 可以被其他
文件使用 。
?,ref 符号名 — 在其他文件中定义, 可以在本文件中使用
的符号 。
?,global 符号名 — 其作用相当于,def,.ref效果之和 。
?,mmregs — 定义存储器映射寄存器的符号名, 这样就可
以用 AR0,PMST等助记符替换实际的存储器地址 。
?,float 数 1,数 2 — 指定的各浮点数连续放置到存储器中
( 从当前段指针开始 ) 。
?,word 数 1,数 2 — 指定的各数 ( 十六进制 ) 连续放置到
存储器中 。
?,space n — 以位为单位, 空出 n位存储空间 。
?,end — 程序块结束 。
4,宏定义和宏调用
? TMS320C54x汇编支持宏语言 。 如果程序中需要多次执
行某段程序, 可以把这段程序定义 ( 宏定义 ) 为一个宏,
然后在需要重复执行这段程序的地方调用这条宏 。
? 宏定义如下:
Macname,macro[parameter 1][,…,parameter n]
……
[.mexit]
.endm
返回本节
5.4 链接器命令文件的编写与使用
? 5.4.1 MEMORY伪指令及其使用
? 5.4.2 SECTIONS伪指令及其使用
返回首页
5.4.1 MEMORY伪指令及其使用
? MEMORY伪指令就是用来指定目标存储器的模型 。
MEMORY伪指令的一般语法为:
? SECTIONS
{
name, [property [,property] [,property],..]
name, [property [,property] [,property],..]
name, [property [,property] [,property],..]
}
返回本节
5.4.2 SECTIONS伪指令及其使用
? SECTIONS伪指令功能如下:
? 说明如何将输入段组合成输出段 。
? 在可执行程序中定义输出段 。
? 指定输出段在存储器中存放的位置 。
? 允许对输出段重新命名 。
图 5-5 例 5-6中段的定位
返回本节
5.5 汇编语言程序编写方法
? 5.5.1 汇编语言源程序格式
? 5.5.2 汇编语言中的常数和字符串
? 5.5.3 汇编源程序中的符号
? 5.5.4 汇编源程序中的表达式
返回首页
5.5.1 汇编语言源程序格式
? 助记符指令一般包含 4个部分, 其一般组成形式
为:
? [标号 ][,] 助记符 [操作数 ] [;注释 ]
1,标号区
? 所有汇编指令和大多数汇编伪指令前面都可以带
有标号, 标号可以长达 32个字符, 由 A~ Z,a~ z、
0~ 9,_,和 $符号组成, 且第一个字符不能是数
字, 区分大小写 。
2,助记符区
? 助记符区不能从第一列开始, 否则被认为是标号 。
3,操作数区
? 操作数区是一个操作数列表, 可以是常数, 符号或常数与
符号构成的表达式 。 操作数间需用,,, 号隔开 。
4,注释区
? 注释区可以从任何一列开始, 可以包含 ASCII字符和空格 。
返回本节
5.5.2 汇编语言中的常数和字符串
表 5-3 COFF常数与字符串
返回本节
5.5.3 汇编源程序中的符号
1,标号
2,局部标号
3,符号常数
4,先定义的符号常数
5,替代符号
表 5-4 可以用在表达式中的运算符
表 5-5 带有绝对符号、可重定位符号的表达式
返回本节
5.5.4 汇编源程序中的表达式
? 表达式可以是常数, 符号或由算术运算符结合的
常 数 和 符 号 。 表 达 式 值 的 有 效 范 围 为 -
32768~32767。
1,运算符 ( 表 5-4 所示 )
2,合格的表达式 ( 表 5-5所示 )
返回本节
5.6 TMS320C54x C语言编程
? 5.6.1 存储器模式
? 5.6.2 寄存器规则
? 5.6.3 函数调用规则
? 5.6.4 中断处理
? 5.6.5 表达式分析
返回首页
5.6.1 存储器模式
1,段
? C54x将存储器处理为程序存储器和数据存储器两
个线性块 。 程序存储器包含可执行代码;数据存
储器主要包含外部变量, 静态变量和系统堆栈 。
编译器的任务是产生可重定位的代码, 允许链接
器将代码和数据定位进合适的存储空间 。 C编译
器对 C 语言编译后除了生成 3 个 基 本 段,
即, text,.data,.bss 外, 还生
成,cinit,.const,.stack,.sysmem段 。
2,C/C++系统堆栈
?,stack不同于 DSP汇编指令定义的堆栈 。 DSP汇编程序中
要将堆栈指针 SP指向一块 RAM,用于保存中断, 调用时
的返回地址, 存放 PUSH指令的压栈内容 。
?,stack定义的系统堆栈实现的功能是保护函数的返回地址,
分配局部变量, 在调用函数时用于传递参数, 保护临时结
果 。
?,stack定义的段大小(堆栈大小)可用链接器选项 -stack
size设定,链接器还产生一个全局符号 _ _STACK_SIZE,
并赋给它等于堆栈长度的值,以字为单位,缺省值为 1K。
3,存储器分配
( 1)运行时间支持函数。
( 2)动态存储器分配。
( 3)静态和全局变量的存储器分配。
( 4)位域 /结构的对准。
返回本节
5.6.2 寄存器规则
? 寄存器规则明确了编译器如何使用寄存器以及在函数调用
过程中如何保护寄存器 。
( 1) 辅助寄存器
( 2) 堆栈指针 SP
( 3) ARP
( 4) 在默认情况下, 编译器总是假定 ST1中的 OVM在硬件
复位时被清 0。 若在汇编代码中对 OVM置位为 1,返回到
C环境时必须复位 。
( 5) 寄存器变量
返回本节
5.6.3 函数调用规则
( 1)局部帧的产生
( 2)参数传递
( 3)函数的返回
返回本节
5.6.4 中断处理
( 1)中断的使能和屏蔽必须由程序员自己来设置。
( 2)中断程序没有参数传递,即使说明,也会被
忽略
( 3)中断处理程序不能被正常的 C程序调用。
( 4)为了使中断程序与中断一致,在相应的中断
矢量中必须放置一条转移指令,可以用,sect汇编
伪指令建立一个简单的跳转指令表来完成此项功
能。
( 5)在汇编语言中,注意在符号名前面加上一个
下划线,例如 c_int00记为 _ c_int00。
( 6) 中断程序使用的所有寄存器,包括状态寄存
器和程序中调用函数使用的寄存器都必须予以保
护。
( 7) TMS320C54x C编译器将 C语言进行了扩展,
中断可以利用 interrupt关键字由 C/C++函数直接
处理。
返回本节
5.6.5 表达式分析
? 当 C程序中需要计算整型表达式时, 必须注意以
下几点:
( 1) 算术上溢和下溢 。
( 2) 整除和取模 。
( 3) C代码对 16位乘法结果高 16位的访问 。
返回本节
5.7 用 C语言和汇编语言混合编程
? 5.7.1 独立的 C模块和汇编模块接口
? 5.7.2 从 C程序中访问汇编程序变量
? 5.7.3 在 C程序中直接嵌入汇编语句
返回首页
5.7.1 独立的 C模块和汇编模块接口
? 在编写独立的汇编程序时, 必须注意以下几点:
( 1) 不论是用 C语言编写的函数还是用汇编语言编
写的函数, 都必须遵循寄存器使用规则 。
( 2) 必须保护函数要用到的几个特定寄存器 。
( 3) 中断程序必须保护所有用到的寄存器 。
( 4) 从汇编程序调用 C函数时, 第一个参数 ( 最左
边 ) 必须放入累加器 A中, 剩下的参数按自右向
左的顺序压入堆栈 。
( 5) 调用 C函数时, 注意 C函数只保护了几个特定的
寄存器, 而其他是可以自由使用的 。
( 6) 长整型和浮点数在存储器中存放的顺序是低位
字在高地址, 高位字在低地址 。
( 7) 如果函数有返回值, 返回值存放在累加器 A中 。
( 8) 汇编语言模块不能改变由 C模块产生的,cinit段,
如果改变其内容将会引起不可预测的后果 。
( 9) 编译器在所有标识符 ( 函数名, 变量名等 )
前加下划线, _” 。
( 10) 任何在汇编程序中定义的对象或函数, 如果
需要在 C程序中访问或调用, 则必须用汇编指
令,global定义 。
( 11) 编辑模式 CPL指示采用何种指针寻址, 如果
CPL=1,则采用堆栈指针 SP寻址;如果 CPL=0,
则选择页指针 DP进行寻址 。
返回本节
5.7.2 从 C程序中访问汇编程序变量
? 从 C程序中访问在汇编程序中定义的变量或常数,
可以分为以下 3种情况:
( 1) 访问在,bss块中定义的变量
( 2) 对于访问不在,bss块中定义的变量
( 3) 对于在汇编程序中用,set和,global伪指令定
义的全局常数, 也可以使用特殊的操作从 C程序
中访问它们 。
返回本节
5.7.3 在 C程序中直接嵌入汇编语句
? 在 C程序中嵌入汇编语句是一种直接的 C模块和汇
编模块接口方法 。 采用这种方法一方面可以在 C
程序中实现用 C语言难以实现的一些硬件控制功
能 。 另一方面, 也可以用这种方法在 C程序中的
关键部分用汇编语句代替 C语句以优化程序 。
? 采用这种方法的一个缺点是它比较容易破坏 C环
境, 因为 C编译器在编译嵌入了汇编语句的 C程序
时并不检查或分析所嵌入的汇编语句 。
返回本节
? 5.1 软件开发过程及开发工具
? 5.2 公共目标文件格式
? 5.3 常用汇编伪指令
? 5.4 链接器命令文件的编写与使用
? 5.5 汇编语言程序编写方法
? 5.6 TMS320C54x C语言编程
? 5.7 用 C语言和汇编语言混合编程
5.1 软件开发过程及开发工具
1,建立源程序
2,C编译器 ( C Compiler)
3,汇编器 ( Assembler)
4,连接器 ( Linker)
5,调试工具
6.十六进制转换公用程序( Hex Conversion Utility)
返回首页
图 5-1 TMS320C54x DSP软件开发流程
表 5-1 TMS320C54xV3.50版代码
生成工具程序
返回本节
5.2 公共目标文件格式
? 5.2.1 COFF文件的基本单元 ——段
? 5.2.2 汇编器对段的处理
? 5.2.3 链接器对段的处理
? 5.2.4 重新定位
? 5.2.5 程序装入
? 5.2.6 COFF文件中的符号
返回首页
5.2.1 COFF文件的基本单元 ——段
? 段 ( sections) 是 COFF文件中最重要的概念 。
一个段就是最终在存储器映象中占据连续空间的
一个数据或代码块 。 目标文件中的每一个段都是
相互独立的 。 一般地, COFF目标文件包含 3个缺
省的段,text段, data段, bss段 。
? 段可以分为两大类,即已初始化段和未初始化段。
如图 5-2所示为目标文件中的段与目标系统中存储
器的关系。
图 5-2 目标文件中的段与目标存储器的关系
返回本节
5.2.2 汇编器对段的处理
1,未初始化段
? 未初始化段主要用来在存储器中保留空间, 通常将它们定
位到 RAM中 。 这些段在目标文件中没有实际内容, 只是
保留空间而已 。 程序可以在运行时利用这些空间建立和存
储变量 。 未初始化段是通过使用,bss和,usect汇编伪指令
建立的, 两条伪指令的句法分别为:
.bss 符号, 字数
符号,usect“段名,, 字数
2,已初始化段
? 已初始化段包含可执行代码或已初始化数据 。 这
些段的内容存储在目标文件中, 加载程序时再放
到 TMS320C54X存储器中 。 三个用于建立初始化
段的伪指令句法分别为:
.text [段起点 ]
.data [段起点 ]
.sect,段名, [,段起点 ]
3,命名段
? 命名段就是程序员自己定义的段,它与缺省
的,text,.data和,bss段一样使用,但与缺省段分
开汇编。 data段不同的存储器中,将未初始化的
变量汇编到与,bss段不同的存储器中。产生命
名段的伪指令为:
符号,usect,段名,, 字数
.sect,段名, [,段起点 ]
4,子段
? 子段 ( Subsections) 是大段中的小段 。 链接器
可以像处理段一样处理子段 。 采用子段可以使存
储器图更加紧密 。 子段的命名句法为:
基段名:子段名
? 子段也有两种, 用,sect命令建立的是已初始化段,
用,usect命令建立的是未初始化段 。
5,段程序计数器 ( SPC)
? 汇编器为每个段安排一个独立的程序计数器,即
段程序计数器( SPC)。 SPC表示一个程序代码
段或数据段内的当前地址。开始时,汇编器将每
个 SPC置 0,当汇编器将程序代码或数据加到一
个段内时,相应的 SPC增加。如果汇编器再次遇
到相同段名的段,继续汇编至相应的段,且相应
的 SPC在先前的基础上继续增加。
图 5-3 例 5-1产生的目标代码 返回本节
5.2.3 链接器对段的处理
? 链接器对段的处理有两个功能 。 首先, 它将汇编
器产生的 COFF目标文件 (,obj文件 ) 中的各种段
作为输入段, 当有多个文件进行链接时, 它将输
入段组合起来, 在可执行的 COFF输出模块中建
立各个输出段 。 其次, 链接器为输出段选择存储
器地址 。
? 链接器有两个命令完成上述功能, 即:
? MEMORY 命令 ——定义目标系统的存储器配置
图, 包括对存储器各部分的命名, 以及规定它们
的起始地址和长度 。
? SECTIONS命令 ——告诉链接器如何将输入段组
合成输出段,以及在存储器何处存放输出段。子
段可以用来更精确地编排段,可用链接器
SECTIONS命令指定子段。
图 5-4 链接器默认的存储器分配
返回本节
5.2.4 重新定位
1,链接时 重新定位
? 将各个段定位到存储器中, 每个段都从合适的地
址开始 。
? 将符号值调整到相对于新的段地址的数值 。
? 调整对重新定位后符号的引用 。
2,运行时重新定位
? 将代码装入存储器的一个地方, 而运行在另一个
地方 。 利用 SECTIONS命令选项让链接器定位两
次 。 一些关键的执行代码必须装入在系统的 ROM
中, 但希望在较快的 RAM中运行 。
? 链接器提供了一个简单的处理该问题的方法 。 利
用 SECTIONS命令选项让链接器定位两次 。 第一
次使用装入关键字设置装入地址, 再用运行关键
字设置运行地址 。
返回本节
5.2.5 程序装入
( 1) 硬件仿真器和 CCS集成开发环境, 具有内部
的装入器, 调用装入器的 LOAD命令即可装入可
执行程序 。
( 2) 将代码固化在片外存储器中, 采用 Hex转换工
具 ( Hex conversion utility), 例如 Hex500将
可执行的 COFF目标模块 (,out文件 ) 转换成几
种其他目标格式文件, 然后将转换后的文件用编
程器将代码写入 EPROM/Flash。
返回本节
5.2.6 COFF文件中的符号
? COFF文件中有一个符号表, 用于存储程序中的
符号信息 。 链 接器对符号重定位时使用该表, 调
试工具也使用该表来提供符号调试 。
? 外部符号指在一个模块中定义, 在另一个模块中
使用的符号 。 可使用,def,.ref或,global汇编伪
指令将符号定义为外部符号 。,def在当前模块中
定义, 可以在别的模块中使用的符号;,ref在当
前 模 块 中 引 用, 但 在 别 的 模 块 中 定 义 的 符
号;,global可用于以上任何一种情况 。
返回本节
5.3 常用汇编伪指令
返回首页
表 5-2 常用的汇编 伪指令
1,段定义伪指令
? 为便于链接器将程序, 数据分段定位于指定的 ( 物理存在
的 ) 存储器空间, 并将不同的 obj文件链接起来 。 段的使
用非常灵活, 但常用以下约定:
?,text — 此段存放程序代码 。
?,data — 此段存放初始化了的数据 。
?,bss — 此段存入未初始化的变量 。
?,sect '名称 ' — 定义一个有名段, 放初始化了的数据或程
序代码 。
2,条件汇编伪指令
?,if,.elseif,.else,.endif伪指令告诉汇编器按照表达式
的计算结果对代码块进行条件汇编 。
?,if expression — 标志条件块的开始, 仅当条件为真
( expression的值非 0即为真 ) 时汇编代码 。
?,elseif expression — 标志若,if条件为假, 而,elseif条件
为真时要汇编代码块 。
?,else — 标志若,if条件为假时要汇编代码块 。
?,endif — 标志条件块的结束, 并终止该条件代码块 。
3,引用其他文件和初始化常数伪指令
?,include '文件名 ' — 将指定文件复制到当前位置, 其内
容可以是程序, 数据, 符号定义等 。
?,copy '文件名 ' — 与,include类似 。
?,def 符号名 — 在当前文件中定义一个符号, 可以被其他
文件使用 。
?,ref 符号名 — 在其他文件中定义, 可以在本文件中使用
的符号 。
?,global 符号名 — 其作用相当于,def,.ref效果之和 。
?,mmregs — 定义存储器映射寄存器的符号名, 这样就可
以用 AR0,PMST等助记符替换实际的存储器地址 。
?,float 数 1,数 2 — 指定的各浮点数连续放置到存储器中
( 从当前段指针开始 ) 。
?,word 数 1,数 2 — 指定的各数 ( 十六进制 ) 连续放置到
存储器中 。
?,space n — 以位为单位, 空出 n位存储空间 。
?,end — 程序块结束 。
4,宏定义和宏调用
? TMS320C54x汇编支持宏语言 。 如果程序中需要多次执
行某段程序, 可以把这段程序定义 ( 宏定义 ) 为一个宏,
然后在需要重复执行这段程序的地方调用这条宏 。
? 宏定义如下:
Macname,macro[parameter 1][,…,parameter n]
……
[.mexit]
.endm
返回本节
5.4 链接器命令文件的编写与使用
? 5.4.1 MEMORY伪指令及其使用
? 5.4.2 SECTIONS伪指令及其使用
返回首页
5.4.1 MEMORY伪指令及其使用
? MEMORY伪指令就是用来指定目标存储器的模型 。
MEMORY伪指令的一般语法为:
? SECTIONS
{
name, [property [,property] [,property],..]
name, [property [,property] [,property],..]
name, [property [,property] [,property],..]
}
返回本节
5.4.2 SECTIONS伪指令及其使用
? SECTIONS伪指令功能如下:
? 说明如何将输入段组合成输出段 。
? 在可执行程序中定义输出段 。
? 指定输出段在存储器中存放的位置 。
? 允许对输出段重新命名 。
图 5-5 例 5-6中段的定位
返回本节
5.5 汇编语言程序编写方法
? 5.5.1 汇编语言源程序格式
? 5.5.2 汇编语言中的常数和字符串
? 5.5.3 汇编源程序中的符号
? 5.5.4 汇编源程序中的表达式
返回首页
5.5.1 汇编语言源程序格式
? 助记符指令一般包含 4个部分, 其一般组成形式
为:
? [标号 ][,] 助记符 [操作数 ] [;注释 ]
1,标号区
? 所有汇编指令和大多数汇编伪指令前面都可以带
有标号, 标号可以长达 32个字符, 由 A~ Z,a~ z、
0~ 9,_,和 $符号组成, 且第一个字符不能是数
字, 区分大小写 。
2,助记符区
? 助记符区不能从第一列开始, 否则被认为是标号 。
3,操作数区
? 操作数区是一个操作数列表, 可以是常数, 符号或常数与
符号构成的表达式 。 操作数间需用,,, 号隔开 。
4,注释区
? 注释区可以从任何一列开始, 可以包含 ASCII字符和空格 。
返回本节
5.5.2 汇编语言中的常数和字符串
表 5-3 COFF常数与字符串
返回本节
5.5.3 汇编源程序中的符号
1,标号
2,局部标号
3,符号常数
4,先定义的符号常数
5,替代符号
表 5-4 可以用在表达式中的运算符
表 5-5 带有绝对符号、可重定位符号的表达式
返回本节
5.5.4 汇编源程序中的表达式
? 表达式可以是常数, 符号或由算术运算符结合的
常 数 和 符 号 。 表 达 式 值 的 有 效 范 围 为 -
32768~32767。
1,运算符 ( 表 5-4 所示 )
2,合格的表达式 ( 表 5-5所示 )
返回本节
5.6 TMS320C54x C语言编程
? 5.6.1 存储器模式
? 5.6.2 寄存器规则
? 5.6.3 函数调用规则
? 5.6.4 中断处理
? 5.6.5 表达式分析
返回首页
5.6.1 存储器模式
1,段
? C54x将存储器处理为程序存储器和数据存储器两
个线性块 。 程序存储器包含可执行代码;数据存
储器主要包含外部变量, 静态变量和系统堆栈 。
编译器的任务是产生可重定位的代码, 允许链接
器将代码和数据定位进合适的存储空间 。 C编译
器对 C 语言编译后除了生成 3 个 基 本 段,
即, text,.data,.bss 外, 还生
成,cinit,.const,.stack,.sysmem段 。
2,C/C++系统堆栈
?,stack不同于 DSP汇编指令定义的堆栈 。 DSP汇编程序中
要将堆栈指针 SP指向一块 RAM,用于保存中断, 调用时
的返回地址, 存放 PUSH指令的压栈内容 。
?,stack定义的系统堆栈实现的功能是保护函数的返回地址,
分配局部变量, 在调用函数时用于传递参数, 保护临时结
果 。
?,stack定义的段大小(堆栈大小)可用链接器选项 -stack
size设定,链接器还产生一个全局符号 _ _STACK_SIZE,
并赋给它等于堆栈长度的值,以字为单位,缺省值为 1K。
3,存储器分配
( 1)运行时间支持函数。
( 2)动态存储器分配。
( 3)静态和全局变量的存储器分配。
( 4)位域 /结构的对准。
返回本节
5.6.2 寄存器规则
? 寄存器规则明确了编译器如何使用寄存器以及在函数调用
过程中如何保护寄存器 。
( 1) 辅助寄存器
( 2) 堆栈指针 SP
( 3) ARP
( 4) 在默认情况下, 编译器总是假定 ST1中的 OVM在硬件
复位时被清 0。 若在汇编代码中对 OVM置位为 1,返回到
C环境时必须复位 。
( 5) 寄存器变量
返回本节
5.6.3 函数调用规则
( 1)局部帧的产生
( 2)参数传递
( 3)函数的返回
返回本节
5.6.4 中断处理
( 1)中断的使能和屏蔽必须由程序员自己来设置。
( 2)中断程序没有参数传递,即使说明,也会被
忽略
( 3)中断处理程序不能被正常的 C程序调用。
( 4)为了使中断程序与中断一致,在相应的中断
矢量中必须放置一条转移指令,可以用,sect汇编
伪指令建立一个简单的跳转指令表来完成此项功
能。
( 5)在汇编语言中,注意在符号名前面加上一个
下划线,例如 c_int00记为 _ c_int00。
( 6) 中断程序使用的所有寄存器,包括状态寄存
器和程序中调用函数使用的寄存器都必须予以保
护。
( 7) TMS320C54x C编译器将 C语言进行了扩展,
中断可以利用 interrupt关键字由 C/C++函数直接
处理。
返回本节
5.6.5 表达式分析
? 当 C程序中需要计算整型表达式时, 必须注意以
下几点:
( 1) 算术上溢和下溢 。
( 2) 整除和取模 。
( 3) C代码对 16位乘法结果高 16位的访问 。
返回本节
5.7 用 C语言和汇编语言混合编程
? 5.7.1 独立的 C模块和汇编模块接口
? 5.7.2 从 C程序中访问汇编程序变量
? 5.7.3 在 C程序中直接嵌入汇编语句
返回首页
5.7.1 独立的 C模块和汇编模块接口
? 在编写独立的汇编程序时, 必须注意以下几点:
( 1) 不论是用 C语言编写的函数还是用汇编语言编
写的函数, 都必须遵循寄存器使用规则 。
( 2) 必须保护函数要用到的几个特定寄存器 。
( 3) 中断程序必须保护所有用到的寄存器 。
( 4) 从汇编程序调用 C函数时, 第一个参数 ( 最左
边 ) 必须放入累加器 A中, 剩下的参数按自右向
左的顺序压入堆栈 。
( 5) 调用 C函数时, 注意 C函数只保护了几个特定的
寄存器, 而其他是可以自由使用的 。
( 6) 长整型和浮点数在存储器中存放的顺序是低位
字在高地址, 高位字在低地址 。
( 7) 如果函数有返回值, 返回值存放在累加器 A中 。
( 8) 汇编语言模块不能改变由 C模块产生的,cinit段,
如果改变其内容将会引起不可预测的后果 。
( 9) 编译器在所有标识符 ( 函数名, 变量名等 )
前加下划线, _” 。
( 10) 任何在汇编程序中定义的对象或函数, 如果
需要在 C程序中访问或调用, 则必须用汇编指
令,global定义 。
( 11) 编辑模式 CPL指示采用何种指针寻址, 如果
CPL=1,则采用堆栈指针 SP寻址;如果 CPL=0,
则选择页指针 DP进行寻址 。
返回本节
5.7.2 从 C程序中访问汇编程序变量
? 从 C程序中访问在汇编程序中定义的变量或常数,
可以分为以下 3种情况:
( 1) 访问在,bss块中定义的变量
( 2) 对于访问不在,bss块中定义的变量
( 3) 对于在汇编程序中用,set和,global伪指令定
义的全局常数, 也可以使用特殊的操作从 C程序
中访问它们 。
返回本节
5.7.3 在 C程序中直接嵌入汇编语句
? 在 C程序中嵌入汇编语句是一种直接的 C模块和汇
编模块接口方法 。 采用这种方法一方面可以在 C
程序中实现用 C语言难以实现的一些硬件控制功
能 。 另一方面, 也可以用这种方法在 C程序中的
关键部分用汇编语句代替 C语句以优化程序 。
? 采用这种方法的一个缺点是它比较容易破坏 C环
境, 因为 C编译器在编译嵌入了汇编语句的 C程序
时并不检查或分析所嵌入的汇编语句 。
返回本节