1
信息工程学通信工程系
DSP技术 及应用
Digital Signal Processor
数字信号处理器
陈金鹰 副教授
2
第四章 DSP软件开发过程
第一节 汇编语言程序的编写方法
第二节 汇编语言程序的汇编
第三节 COFF的一般概念
第四节 目标文件 的链接
3
软件开发过程
第一节 汇编语言程序的编写方法
4
汇编语言程序的编辑、汇编和链接过程
5
1,汇编语言源程序的句法格式
要点 以,asm为扩展名每一行由 4个部分组成
格式
[标号 ][,] 空格 [助记符 ] 空格 [操作数 ] 空格 [;注释 ]
[ ]中的
内容为可
选择部分
供本程序的其它部分或其它程序调
用。标号是任选项,标号后面可以
加也可以不加冒号,,, 。
6
要 点
1.标号必须从第1列写起,
2.标号最多可达 32个字符,可以是 A~ Z,a~ z,0~ 9,
_,以及 $,但标号的第 1个字符不能是数字。
3.引用标号时,标号的大小写必须一致。
4.标号的值就是段程序计数器 SPC的值。
5.如果不用标号,则第一个字母必须为空格、分号
或星号( *)。
7
要点
建议
[标号 ][,] 空格 [助记符 ] 空格 [操作数 ] 空格 [;注释 ]
可以是助记符指令、汇编指令、宏
指令和宏调用命令。
1.助记符指令,一般用大写;
2.汇编命令和宏命令,以句号,,”
开始,且为通常用小写。
8
要点
[标号 ][,] 空格 [助记符 ] 空格 [操作数 ] 空格 [;注释 ]
1.指令中的操作数或汇
编命令中定义的内容
2.操作数之间必须用逗
号,,, 分开。
1.从分号, ;, 开始
2.可以放在指令或汇编命令后面,
也可以放在单独的一行或数行。
要点
9
2,汇编语言源程序的数据型式
二进制:如 1110001b或 1111001B;
八进制,226q或 572Q;
十进制,1234或 +1234或 -1234( 缺省型 )
十六进制,0A40h或 0A40H或 0xA40
浮点数,1.623e-23( 仅 C语言程序中能用, 汇编程序不能用 )
字符,‘ D’
字符串:, this is a string”
10
3,汇编命令
汇编命令是用来为程序提供数据和控制汇编进程的 。 C54x汇
编器共有 64条汇编命令, 根据它们的功能, 可以将汇编命令
分成 8类:
( 1) 对各种段进行定义的命令 。
( 2) 对常数 ( 数据和存储器 ) 进行初始化的命令 。
( 3) 调整 SPC( 段寄存器 ) 的指令 。
( 4) 对输出列表文件格式化的命令 。
( 5) 引用其它文件的命令 。
( 6) 控制条件汇编的命令 。
( 7) 在汇编时定义符号的命令 。
( 8) 执行其它功能的命令 。
11
例 4-1 编写计算 y=a1*x1+a2*x2+a3*x3+a4*x4的汇编源程序
* * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * *
* example.asm y=a1*x1+a2*x2+a3*x3+a4*x4 *
* * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * *
.title,example.asm” ;为汇编源程序取名
.mmregs ;定义存储器映象寄存器
STACK,usect,STACK”,10h ;分配 10个单元的堆栈空间
.bss a,4 ;为系数 a分配 4个单元的空间
.bss x,4 ;为变量 x分配 4个单元的空间
.bss y,1 ;为结果 y 分配 1个单元的空间
.def _c_int00 ;定义标号 _c_int00
.data ;定义数据代码段
table,.word 1,2,3,4 ;在标号 table开始的 8个单元

.word 8,6,4,2 ;为这 8个单元赋初值
12
.text ;定义文本代码段
_c_int00:STM #0,SWWSR ;软件等待状态寄存器置 0,不设等待
STM #STACK+10h,SP ;设置堆栈指针初值
STM #a,AR1 ;AR1 指向 a的地址
RPT #7 ;从程序存储器向数据存储器
MVPD table,*AR1+;重复传送 8个数据
CALL SUM ;调用 SUM 实现乘法累加和的子程序
end,B end ;循环等待
SUM:STM #a,AR3 ;将系数 a的地址赋给 AR3
STM #x,AR4 ;将变量 x的地址赋给 AR3
RPTZ A,#3 ;将 A清 0,并重复执行下条指令 4次
MAC *AR3+,*AR4+,A ;执行乘法并累加, 结果放在 A中
STL A,@y ;将 A的低字内容送结果单元 y
RET ;结束子程序
.end ;结束全部程序
13
4,宏定义和宏调用
( 1) 两者都可以被多次调用, 但是把子
程序汇编成目标代码的过程只进行一次,
而在用到宏指令的每个地方都要对宏指令
中的语句逐条地进行汇编 。
( 2) 在调用前, 由于子程序不使用参数,
故子程序所需要的寄存器等都必须事先设
置好;而对于宏指令来说, 由于可以使用
参数, 调用时只要直接代入参数就行了 。
( 3) 宏指令可以在源程序的任何位置上
定义, 但必须在用到它之前先定义好 。 宏
定义可以嵌套 。
宏指
令与
子程
序 的
异同
14
macname,macro[parameter 1][,…,parameter n]
助记符指令 与宏指令
[.mexit]
.endm
宏定义的格式
宏调用的格式
[label][,]macname [parameter1][,…,parametern]
15
1 *
2
3 * add3
4 *
5 * ADDRP=P1+P2+P3 ;说明宏功能
6
7 add3,macro p1,p2,p3,ADDRP;定义宏
8
9 LD p1,A ;将参数 1赋给 A
10 ADD p2,A ;将参数 2与 A相加
11 ADD p3,A ;将参数 3与 A相加
12 STL A,ADDRP ;将结果 A的低字存参数 4
13,endm ;结束宏
14
15
16,global abc,def,ghi,adr;定义全局符号
17
18 000000 add3 abc,def,ghi,adr;调用宏
1
1 000000 1000! LD abc,A ;宏展开
1 000001 0000! ADD def,A
1 000002 0000! ADD ghi,A
1 000003 8000! STL A,adr
例 4-2 宏定义、宏调用和宏展开的一个例子。
16
第二节 汇编语言程序的汇编
汇编语言源程序要素 汇编命令助记符指令
宏命令
汇编程序 ( 汇编器 ) 功能
将源程序汇编成可重定位的目标文件 (,obj文件 ) ;
如果需要, 可以生成一个列表文件 (,lst文件 ) ;
将程序代码分段, 每段的目标代码都有一个 SPC管理;
定义和引用全局符号, 可在列表后附加交叉引用表;
对条件程序块进行汇编;
支持宏功能, 允许定义宏命令 。
17
1,运行汇编程序
axm500 [input file[object file[listing file]]][-options]
汇编器是名为 asm500.exe的可执行程序
例如
axm500 cjy.asm -l -s -x
源程序 cjy.asm经汇编后将生成一个 cjy,obj目标
文件, 列表文件, 符号表 ( 在目标文件中 ) 以及交
叉引用表 ( 在列表文件中 ) 。
18
2,列表文件
TMS320C54x COFF Assembler Version 3.70 Tue Oct 19 12:42:59 2004
Copyright (c) 1996-2001 Texas Instruments Incorporated
example.asm PAGE 1
1 * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * *
2 * example.asm y=a1*x1+a2*x2+a3*x3+a4*x4 *
3 * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * *
5,mmregs ;定义存储器映象寄存器
6 000000 STACK,usect "STACK",10h ;分配 10个单元的堆栈空间
7 000000,bss a,4 ;为系数 a分配 4个单元的空间
8 000004,bss x,4 ;为变量 x分配 4个单元的空间
9 000008,bss y,1 ;为结果 y 分配 1个单元的空间
10,global _c_int00 ;定义标号
列表文件中包括源程序语句和目标代码
19
11 000000,data ;定义数据代码段
12 000000 0001 table,.word 1,2,3,4 ;在标号 table开始的 8个单元中
000001 0002
000002 0003
000003 0004
13 000004 0008,word 8,6,4,2 ;为这 8个单元赋初值
000005 0006
000006 0004
000007 0002
14 000000,text ;定义文本代码段
15 000000 7728 _c_int00 STM #0,SWWSR ;软件等待状态寄存器置 0,不设等待
000001 0000
16 000002 7718 STM #STACK+10h,SP ;设置堆栈指针初值
000003 0010-
17 000004 7711 STM #a,AR1 ;AR1 指向 a的地址
000005 0000-
18 000006 EC07 RPT #7 ;从程序存储器向数据存储器
19 000007 7C91 MVPD table,*AR1+ ;重复传送 8个数据
000008 0000"
源文件的每一行都会在列表文件
中生成一行。包括行号、段程序
计数器 SPC的数值、汇编后的目
标代码、源程序语句。
一条指令可以生成 1或 2个字的目标代码。
第 2字单独列一行,列出了
SPC的数值和目标代码 。
20
20 000009 F074 CALL SUM ;调用 SUM 实现乘法累加和的子程序
00000a 000D'
21 00000b F073 end,B end ;循环等待
00000c 000B'
22 00000d 7713 SUM,STM #a,AR3 ;将系数 a的地址赋给 AR3
00000e 0000-
23 00000f 7714 STM #x,AR4 ;将变量 x的地址赋给 AR3
000010 0004-
24 000011 F071 RPTZ A,#3 ;将 A清 0,并重复执行下条指令 4次
000012 0003
25 000013 B09A MAC *AR3+,*AR4+,A ;执行乘法并累加, 结果放在 A中
26 000014 8008- STL A,@y ;将 A的低字内容送结果单元 y
27 000015 FC00 RET ;结束子程序
28,end ;结束全部程序
No Assembly Errors,No Assembly Warnings
Field 1源程序语句的
行号,用十进制数表

Field 2段程序计数器
( SPC),用十六进制数表

Field 4:
源程序语

Field 3目标代码
! 未定义的外部引用 。
’,text段重新定位 。
”,data段重新定位 。
+,sect段重新定位 。
-,bss和,usect段重新定位 。
21
在运行汇编程序时, 还可产生交叉引用清单, 清单包
括符号, 定义和引用的位置 。
交叉引用清单
LABEL VALUE DEFN REF
INT0 0002+ 19 1
ISR2 REF 3 21
proc REF 4 28
列出汇编时
定义和引用
的每个符号
列出一个赋给符
号的 4位十六进
制数值, 或说明
符号属性的字符
或名称 。
列出引用此符
号的语句的行
号 。 如果此栏
是空格, 表示
此符号还没有
被引用过 。
列出定义符号的语
句编号 。 如果此符
号未加定义, 则此
栏是空格 。
22
REF,外部引用 (,globa)
UNDF:未曾定义过
’,在,text段定义的符号 。
”,在,data段定义的符号 。
+,在,sect段定义的符号 。
-,在,bss或,usect段定义的符号 。
交叉引用清单中符号的属性
23
建立公共目标文件
格式 的 目标文件
第三节 COFF的一般概念
汇编器

链接器
功能 的异同
相同点
不同点 汇编器 建立的是相对地
址 COFF文件,
即,obj文件
链接器 建立
的是绝对地
址 COFF文件,
即,out文件
汇编器根据汇编命令用适当的段将各部分
程序代码和数据连在一起,构成目标文件;
链接器的一个任务就是分配存储单元,即
把各个段重新定位到目标存储器中。
24
1,COFF文件中的段
不同种类的区别
COFF文件种 类
C54x汇编器和 C编译器建立的是 COFF2文件 。
C54x能够读 /写所有形式的 COFF文件, 缺省值下
链接器生成的是 COFF2文件, 用链接器- vn选项
可以选择不同形式的 COFF文件 。
COFF0
COFF1
COFF2
标题格式不相同
数据部分是相同
25
段 ( sections) 的概念
特点
定义
分段的优点,在目标文件中将放置程
序, 数据, 变量的代码分开, 便于在链
接时作为一个单独的部分分配存储器 。
由于大多数系统都有好几种形式的存储
器, 通过对各个段重新定位, 可以使目
标存储器得到更为有效的利用 。
段是在存储器图中占据相
邻空间的代码或数据块 。
一个目标文件中的每一个
段都是分开的和不相同的 。
目标文件中的段与目标存
储器之间的关系
26
2,COFF文件中的符号
用于处理符号
的汇编命令
外部符号
在一个模块中定义 的
定义, 可在另一个模
块中引用的符号。
.def,在当前模块中定义, 并
可在别的模块中使用的符号 。
.ref:在当前模块中使用, 但
在别的模块中定义的符号 。
.global:可以是上面的随便
哪一种情况 。
27
x,ADD #56h,A ;定义 x
B y ;引用 y
.def x ; x在此模块中定义,;可被别的模块引用
.ref y ; y在这里引用,;它在别的模块中定义


汇编时, 汇编器把 x和 y都放在目标文件的符号
表中 。 链接器必须使所引用的符号与相应的定
义相匹配 。 如果链接器不能找到某个符号的定
义, 就给出不能辨认所引用符号的出错信息 。
28
3,汇编器对段的处理
用于定义 段
的汇编命令
.bss 未初始化段
.usect 未初始化自定义段
.text 已初始化程序正文段
.data 已初始化程序数据段
.sect 已初始化自定义段
如果汇编语言程序中一个段命令都
没有用,那么汇编器把程序中的内
容都汇编到,text段。
注意
29
( 1) 未初始化段
未初始化段由,bss和,usect命令建立
位置
为变量 保留存储器空间作用
通常将它们定位到 RAM区
使用方法,bss 符号, 字数
符号,usect,段名,, 字数
对应于保
留的存储
空间第一
个字的变
量名称
程序员为自定义未
初始化段起的名字
30
( 2) 已初始化段
已初始化段是由,text,.data的,sect命令建立
位置
包含有可执行代码或初始化数据作用
通常将它们定位到 EPROM区
使用方法,text [段起点 ].data [段起点 ]
.sect,段名, [,段起点 ]
段程序计
数器( SPC)
定义的一
个起始值。
程序员为自定义未
初始化段起的名字
31
( 3) 子段
位置
子段结构,可以使存储器分配图更加紧密。
可单独分配空间或在基段位置之后
使用方法 基段名:子段名.sect,.text:_func”
子段也有两种:用,sect命令建立的是已初始化
段,而用,usect命令建立的段是未初始化段。
作用
32
( 4) 段程序计数器 ( SPC)
编址
过程
表示一个程序代码段或数据段内的当前地址作用
一开始,汇编器将每个 SPC置 0。当
汇编器将程序代码或数据加到一个
段内时,相应的 SPC就增加。如果再
继续对某个段汇编,则相应的 SPC就
在先前的数值上继续增加。链接器
在链接时要对每个段进行重新定位。
33
例 4-4 段命令应用举例:
2 * * * * * * * * * * * * * * * * * * * * * * * * * *
3 * Assemble an initialized table into,data *
4 * * * * * * * * * * * * * * * * * * * * * * * * * *
5 0000,data
6 0000 0011 coeff,word 011h,022h,033h
0001 0022
0002 0033
7 * * * * * * * * * * * * * * * * * * * * * * * * * *
8 * * Reserve space in,bss for a variable * *
9 * * * * * * * * * * * * * * * * * * * * * * * * * *
10 0000,bss buffer,10
11 * * * * * * * * * * * * * * * * * * * * * * * * * *
12 * * still in,data * *
13 * * * * * * * * * * * * * * * * * * * * * * * * * *
14 0003 0123 ptr,word 0123h
34
15 * * * * * * * * * * * * * * * * * * * * * * * * * *
16 * * Assemble code into the,text section * *
17 * * * * * * * * * * * * * * * * * * * * * * * * * *
18 0000,text
19 0000 100f add,LD 0Fh,A
20 0001 f010 aloop,SUB #1,A
0002 0001
21 0003 f842 BC aloop,AGEQ
0004 0001’
22 * * * * * * * * * * * * * * * * * * * * * * * * * *
23 * * Another initialized table into,data * *
24 * * * * * * * * * * * * * * * * * * * * * * * * * *
25 0004,data
26 0004 00aa ivals,word 0Aah,0BBh,0CCh
0005 00bb
0006 00cc
35
27 * * * * * * * * * * * * * * * * * * * * * * * * * *
28 * * Define another section for more variables * *
29 * * * * * * * * * * * * * * * * * * * * * * * * * *
30 0000 var2,usect,newvars”,1
31 0001 inbuf,usect,newvars”,7
32 * * * * * * * * * * * * * * * * * * * * * * * * * *
33 * * Assemble more code into,text * *
34 * * * * * * * * * * * * * * * * * * * * * * * * * *
35 0005,text
36 0005 110a mpy,LD 0Ah,B
37 0006 f166 mloop,MPY #0Ah,B
0007 000a
38 0008 f868 BC mloop,BNOV
0009 0006’
39 * * * * * * * * * * * * * * * * * * * * * * * * * *
40 * * Define a named section for int,vectors * *
41 * * * * * * * * * * * * * * * * * * * * * * * * * *
42 0000,sect,vectors”
43 0000 0011,word 011h,033h
44 0001 0033
36
在此例中, 一共建立了 5个段:
.text 段内有 10个字的程序
代码 。
.data 段内有 7个字的数据 。
vectors 是一个用,sect建
立的自定义段, 段内
有 2个字的已初始化数
据 。
.bss 在存储器中为变量保
留 10个存储单元 。
newvars是一个用,usect命令
建立的自定义段, 它
在存储器中为变量保
留 8个存储单元 。
37
第四节 目标文件 的链接
链接器
主要
功能
根据链接命令或链接命令文件
(,cmd文件),将一个或多个 COFF
目标文件链接起来,生成存储器映
象文件(,map)和可执行的输出文
件(,out)( COFF目标模块)
38
1,运行链接程序
( 1) 键入命令 lnk500
( 2) 键入命令 lnk500 file1.obj file2.obj –o
( 3) 键入命令 lnk500 linker.cmd
链接器 是 名为 lnk500.exe 的可执行程序
应包含如下内容:
file1.obj
file2.obj
-o lind.out
2,链接器选项
建立一个名为 a.out
(默认情况)的可重新
定位的输出模块。
39
3.链接器对段的处理
( 1) 把一个或多个 COFF目标文件中的各种段作为链接
器的输入段, 经链接后在一个可执行的 COFF输出模块
中建立各个输出段 。
( 2) 为各个输出段选定存储器地址 。
链接器在对段进行处理时, 主要完成
汇编器在需要引用重新定位的符号处都留
了一个重定位入口。链接器对符号重定位
时,利用这些入口修正对符号的引用值。
40
( 1)将各个段定位到存储器分配图中,这样一来每
个段都从一个恰当的地址开始。
( 2)将符号的数值调整到相对于新的段地址的数值。
( 3)调整对重新定位后符号的引用。
汇编器在需要引用重新定位的符号处都留了一个重定
位入口。链接器对符号重定位时,利用这些入口修正
对符号的引用值。
41链接器将输入段组合成一个可执行的目标模块
42
例 4-5 列表文件中, 汇编器为需要重新定位的符号
所留的重定位入口 。
1 0100 X,set 0100h ;给 X赋值
2 0000,text
3 0000 FO73 B Y ;生成一个重定位入口
0000 0004’
4 0002 F020 LD #X,A ;生成一个重定位入

0003 0000!
5 0004 F7E0 Y,RESET在,text段对 X
的引用是一次
外部引用
.text段内对 Y
的引用是一次
内部引用
.text段内 定义 Y
另一个模块中定义的 X。这里赋初值
43
假设链接时 X重新定位在地址 7100h,.text段重新定
位到从地址 7200h开始, 那么 Y的重定位值为 7204h。
链接器利用两个重定位入口, 对目标文件中的两次引
用进行修正:
f073 B Y 变成 f073
0004’ 7204
f020 LD #X,A 变成 f020
0000! 7100
在 COFF目标文件中有一张重定位入口表 。 链接器
在处理完之后就将重定位入口消去, 以防止在重新链
接或加载时再次重新定位 。
一个没有重定位入口的文件称为绝对
文件,它的所有地址都是绝对地址。
44
4.链接器命令文件
( 1) 将 有多个选项的命令, 写成一个链接
器命令文件,cmd。
( 2) 运行 链接器命令文件,cmd,生成一个
映象文件,map和一个可执行的输出文件,out
( 3) 进行存储器分配




使用方法 lnk500 链接器命令文件 名,cmd
45
例 4-6 链接器命令文件举例 。
a.obj b.obj /* 输入文件名 */
-o prog.out /* 选项 */
-m prog.map /* 选项 */
MEMORY /* MEMORY 命令 */
{
PAGE0,ROM,origin=1000h,length=0100h
PAGE1,RAM,origin=0100h,length=0100h
}
SECTIONS /* SECTIONS 命令 */
{
.text,>ROM
.data,>ROM
.bss,>RAM
}
如果链接器认定一个文件为
目标文件,就对它链接;否
则就假定它是一个命令文件,
并从中读出命令和进行处理。
46
( 1) 输入文件名, 就是要链接的目标文件和
文档库文件, 或者是其它的命令文件 。 如果
要调用另一个命令文件作为输入文件, 此句
一定要放在本命令文件的最后, 因为链接器
不能从新调用的命令文件返回 。
( 2) 链接器选项 。 这些选项既可以用在链接
器命令行, 也可以编在命令文件中 。
( 3) MEMORY和 SECTIONS都是链接器命令。
如果链接命令文件中没有 MEMORY和 SECTIONS
命令(默认情况),则链接器就从地址 0080h
一个段接着一个段进行配置。
( 4) 注释的内容应当用 /*和 */符号括起来。
注意
47
5,两条链接器命令的使用方法
MEMORY命令用来定义目标系统 中所包
含的各种形式的存储器 的存储器配置
图, 包括对存储器各部分命名, 以及
规定它们的起始地址和长度 。 定义系

( 1) MEMORY命令


48
EMEORY
{
PAGE 0,name 1 [( attr) ],origin=constant,length=constant

PAGE n,name n [( attr) ],origin=constant,length=constant
}
MEMORY命令的一般句法
对一个存储空间加以标记, 每一个 PAGE代表一个
完全独立的地址空间 。 页号 n最多可规定为 255,
取决于目标存储器的配置 。 通常 PAGE 0定为程序
存储器, PAGE 1定为数据存储器 。 如果没有规定
PAGE,则链接器就目标存储器配置在 PAGE 0。
49
EMEORY
{
PAGE 0,name 1 [( attr) ],origin=constant,length=constant

PAGE n,name n [( attr) ],origin=constant,length=constant
}
MEMORY命令的一般句法
名字可以包含 8个字符, A~ Z,a~ z,$,.,_均可 。
名字并没有特殊的含义, 用来标记存储器的区间而
已;名字都是内部记号, 不需要保留在输出文件或
者符号表中 。 不同 PAGE上的存储器区间可以取相同
的名字, 但在同一 PAGE内的名字不能相同, 且不许
重叠配置 。
50
EMEORY
{
PAGE 0,name 1 [( attr) ],origin=constant,length=constant

PAGE n,name n [( attr) ],origin=constant,length=constant
}
MEMORY命令的一般句法
任选项, 为命名区规定
1~ 4个属性 。 如果有选项,
应写在括号内 。
当输出段定位到存储器时,
可利用属性加以限制 。
规定一个存储区的起始
地址 。 键入 origin,org
或 o都可以 。 这个值是一
个 16位二进制常数, 可
以用十进制数, 八进制
数或十六进制数表示 。
规定一个存储区的长度,键
入 length,len或 l都可以。
51
R 规定可以对存储器执行读操作 。
W 规定可以对存储器执行写操作 。
X 规定存储器可以装入可执行的程序代码 。
I 规定可以对存储器进行初始化 。
如果一项属性都没有选, 就可以将输出段不受限制
地定位到任何一个存储器位置 。 任何一个没有规定属
性的存储器都默认有全部 4项属性 。
fill:任选项, 不常用, 在句法中未列出, 为没有定位
输出段的存储器空单元填充一个数, 键入 fill或 f均可
。 这是 2个字节的整型常数, 可以是十进制数, 八进
制数或十六进制数表示 。 如 fill=0FFFFh。
属性选项一共有 4项
52
例 4-7 MEMORY命令的使用方法 。
/* Example command file with MEMORY directive */
file1.obj file2.obj /* Input files */
-o prog.out /* Options */
MEMORY
{
PAGE0,ROM,origin=cooh,length=1000h
PAGE1,SCRTCH,origin=60h,length=20h
ONCHIP,origin=80h,length=200h
}
名为 ROM的 程序存储器,4K字 ROM,起始地址 C00h。
名为 SCRATCH的数据存储器,32字 RAM,起始地址 60h。
名为 ONCHIP的数据存储器,512字 RAM,起始地址为 80h。
53
告诉链接器如何将输入段合成输出段
在可执行程序中定义输出段
规定输出段在存储器中的存放位置
允许重新命名输出项 。
( 2) SECTIONS命令


在链接器命令文件中, SECTIONS命令用大写
字母, 紧随其后并用大括号括起来的是关于
输出段的详细说明 。 每一个输出段的说明都
从段名开始 。 段名后面是一行说明段的内容
和如何给段分配存储单元的性能参数 。
注意
54
SECTIONS
{
name,[property,property,property,… ]
name,[property,property,property,… ]
name,[property,property,property,… ]
}
SECTIONS命令的一般句法
性能参数
1) load allocation 定义将输出段加载到存储器中
的 什么位置 。
句法,load=allocation 或者用大于号代替
,load=”
>allocation 或者省掉, load=”
allocation
其中 allocation是关于输出段地址的说明, 即给输
出段分配存储单元 。
55
.text,load=0x1000 将输出段,text定位到一个特定地址 。
.text,>ROM 将输出段,text定位到名为 ROM的存储区 。
.bss,>( RW) 将,bss段定位到属性为 R,W的存储区 。
.text,align=0x80 将,text定位到 0x80开始的存储区 。
.bss,load=block( 0x80) 将,bss定位到一个 n字存储器
块的任何一个位置 ( n为 2的幂次 ) 。
.text,PAGE 0 将输出段,text定位到 PAGE 0。
如果要用到一个以上参数, 可以将它们排成一行,
例如:
.text,>ROM align (16) PAGE( 2)
或者为方便阅读, 可用括号括起来:
.text,load=( ROM align ( 16) PAGE( 2))
56
2) Run allocation 用来定义输出段在存储器的
什么位置上开始运行 。
句法,run=allocation 或者用大于号代替等号
run>allocation
链接器为每个输出段在目标存储器中分配两个地址:
一个是加载的地址, 另一个是执行程序的地址 。 通常,
这两个地址是相同的, 可以认为每个输出段只有一个
地址 。 有时要想把程序的加载和运行区分开 ( 先将程
序加载到 ROM,然后在 RAM中以较快的速度运行 ), 只
要用 SECTIONS命令让链接器对这个段定位两次就行了 。
一次是设置加载地址, 另一次是设置运行地址 。 例如:
.fir load=ROM,run=RAM
57
3) Input sections 用来定义由哪些输入段组
成输出段 。
句法,{input_sections}
大多数情况下, 在 SECTIONS命令中是不列出每个
输入文件的输入段的段名的:
SECTIONS
{
.text:
.data:
.bss
}
这样, 在链接时, 链接器就将所有输入文件
的,text段链接成,text输出段, 其它段也一样 。
58
SECTIONS
{
.text,/* 建立,text 输出段 */
{
f1.obj(,text) /* 链接源于 f1.obj的,text段 */
f2.obj( sec1) /*链接源于 f2.obj的 sec1段 */
f3.obj /*链接源于 f3.obj的所有段 */
f4.obj(,text,sec2) /*链接源于 f4.obj的,text
段和 sec2段 */
}
}
用文件名和段名来明确地规定输入段
59
如果没有利用 MEMORY和 SECTIONS命令, 链接器就按默
认算法来定位输出段:
MEMORY
{
PAGE 0,PROG,origin=0x0080,length=0xFF00
PAGE 1,DATA,origin=0x0080,length=0xFF80
}
SECTIONS
{
.text,PAGE=0
.data,PAGE=0
.cinit,PAGE=0
.bss,PAGE=1
}
(3) MEMORY和 SECTIONS命令的默认算法
所有的,text输入段, 链接成一个,text输
出段, 它是可执行的输出文件;
所有的,data输入段组
合成,data输出段
所有的,bss输入段则组合成一个,bss输出段
.text和,data段定位到
配置为 PAGE 0上的存储
器, 即程序存储空间 。
60
6,多个文件的链接
例 4-8 编写复位向量文件 vextors.asm。
* * * * * * * * * * * * * * * * * * * * * * *
* Reset vector for example.asm *
* * * * * * * * * * * * * * * * * * * * * * *
.title,vectors.asm”
.ref _c_int00
.sect,.vectors”
B _c_int00
.end
引用 example.asm
中,def _c_int00
定义的标号
编写 example.asm见例 4-1。
61
假设目标存储器的配置如下:
程序存储器:
EPROM E000h~ FFFFh( 片外 )
数据存储器:
SPRAM 0060h~ 007Fh( 片内 )
DARAM 0080h~ 017Fh( 片内 )
例 4-9 根据例 4-1和例 4-8编写链接器命令文件
example.cmd。
vectors.obj
example.obj
-o example.out
-m example.map 生成一个映象文件 example.map
生成可执行的输出文件 example.out
汇 编 生 成 目 标 文 件
example.obj和 vectors.obj
62
MWMORY
{
PAGE 0:
EPROM,org=0E000h,len=100h
VECS,org=0FF80h,len=04h
PAGE 1:
SPRAM,org=0060h,len=20h
DARAM,org=0080h,len=100h
}
SECTIONS
{
.text,>EPROM PAGE 0
.data,>EPROM PAGE 0
.bss,>SPRAM PAGE 1
STACK,>DARAM PAGE 1
.vectors,>VECS PAGE 0
}
63
链接后生成一个可执行的输出文件
example.out和映象文件 example.map。 映象文
件中给出了存储器的配置情况, 程序文本段,
数据段, 堆栈段, 向量段在存储器中的定位表,
以及全局符号在存储器中的位置 。
可执行输出文件 example.out装入目标系统
后就可以运行了 。 系统复位后, PC首先指向
00FF80h,这是复位向量地址 。 在这个地址上,
有一条 B _c_int00指令, 程序马上跳转到
_c_int00语句标号, 从程序起始地址 0e000h开
始执行主程序 。
64
例 4-10 由例 4-9得到的映象文件 example.map。
**************************************************************************
TMS320C54x COFF Linker PC Version 3.70
**************************************************************************
>> Linked Thu Oct 21 18:32:22 2004
OUTPUT FILE NAME,< example.out>
ENTRY POINT SYMBOL,"_c_int00" address,0000e000
MEMORY CONFIGURATION
name origin length used attr fill
--------- --------- -------- -------- ---- --------
PAGE 0,EPROM 0000e000 00000100 0000001e RWIX
VECS 0000ff80 00000004 00000002 RWIX
PAGE 1,SPRAM 00000060 00000020 00000009 RWIX
DARAM 00000080 00000100 00000010 RWIX
SECTION ALLOCATION MAP
output attributes/
section page origin length input sections
-------- ---- --------- ----------- ----------------
.text 0 0000e000 00000016
0000e000 00000016 example.obj (.text)
0000e016 00000000 vectors.obj (.text)
65
.data 0 0000e016 00000008
0000e016 00000008 example.obj (.data)
0000e01e 00000000 vectors.obj (.data)
.bss 1 00000060 00000009 UNINITIALIZED
00000060 00000009 example.obj (.bss)
00000069 00000000 vectors.obj (.bss)
STACK 1 00000080 00000010 UNINITIALIZED
00000080 00000010 example.obj (STACK)
.vectors 0 0000ff80 00000002
0000ff80 00000002 vectors.obj (.vectors)
GLOBAL SYMBOLS,SORTED ALPHABETICALLY BY Name
address name
-------- ----
00000060,bss
0000e016,data
0000e000,text
00000060 ___bss__
ffffffff ___cinit__
0000e016 ___data__
0000e01e ___edata__
00000069 ___end__
0000e016 ___etext__
ffffffff ___pinit__
0000e000 ___text__
66
00000000 __lflags
0000e000 _c_int00
ffffffff cinit
0000e01e edata
00000069 end
0000e016 etext
ffffffff pinit
GLOBAL SYMBOLS,SORTED BY Symbol Address
address name
-------- ----
00000000 __lflags
00000060 ___bss__
00000060,bss
00000069 ___end__
00000069 end
0000e000 ___text__
0000e000,text
0000e000 _c_int00
0000e016 etext
0000e016,data
0000e016 ___data__
0000e016 ___etext__
0000e01e edata
0000e01e ___edata__
ffffffff pinit
ffffffff ___cinit__
ffffffff ___pinit__
ffffffff cinit
[18 symbols]
67