1、1,DSP技术及应用,Digital Signal Processor数字信号处理器,2,DSP汇编伪指令,4.3 coff 段4.5 汇编伪指令4.6 宏语言4.7 链接伪指令,3,汇编语言程序的编辑、汇编和链接过程,4,4.5 汇编伪指令,汇编命令是用来为程序提供数据和控制汇编进程的。C54x汇编器共有64条汇编命令,根据它们的功能,可以将汇编命令分成8类:(1)对各种段进行定义的命令。(2)对常数(数据和存储器)进行初始化的命令。(3)调整SPC(段寄存器)的指令。(4)对输出列表文件格式化的命令。(5)引用其它文件的命令。(6)控制条件汇编的命令。(7)在汇编时定义符号的命令。(8)执
2、行其它功能的命令。,5,4.5 汇编伪指令1 、段定义伪指令2、 常数初始化伪指令3、 段程序计数器定位指令.align4、 输出列表指令,6,例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”
3、 ;为汇编源程序取名 .mmregs ;定义存储器映象寄存器STACK .usect “STACK”,10h ;分配10h个单元的堆栈空间 .bss a,4 ;为系数a分配4个单元的空间 .bss x,4 ;为变量x分配4个单元的空间 .bss y,1 ;为结果y 分配1个单元的空间 .def start ;定义标号start .data ;定义数据代码段table: .word 1,2,3,4 ;在标号table开始的8个单元中 .word 8,6,4,2 ;为这8个单元赋初值,7,.text ;定义文本代码段start:STM #0,SWWSR ;软件等待状态寄存器置0,不设等待 STM
4、#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 ;结束全
5、部程序,8,1、段(sections)的概念,特点,定义,分段的优点:在目标文件中将放置程序、数据、变量的代码分开,便于在链接时作为一个单独的部分分配存储器。由于大多数系统都有好几种形式的存储器,通过对各个段重新定位,可以使目标存储器得到更为有效的利用。,段是在存储器图中占据相邻空间的代码或数据块。,一个目标文件中的每一个段都是分开的和不相同的。,目标文件中的段与目标存储器之间的关系,9,2汇编器对段的处理,用于定义段的汇编命令,.bss 未初始化段.usect 未初始化自定义段.text 已初始化程序正文段.data 已初始化程序数据段.sect 已初始化自定义段,如果汇编语言程序中一个段命
6、令都没有用,那么汇编器把程序中的内容都汇编到.text段。,10,(1)未初始化段,未初始化段由.bss和.usect命令建立,位置,为变量保留存储器空间,作用,通常将它们定位到RAM区,使用方法,.bss 符号 , 字数 符号 .usect “段名”,字数,对应于保留的存储空间第一个字的变量名称,程序员为自定义未初始化段起的名字,11,例4-1 编写计算y=a1*x1+a2*x2+a3*x3+a4*x4的汇编源程序* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * example.asm y=a1*x1+a2*x
7、2+a3*x3+a4*x4 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * .title “example.asm” ;为汇编源程序取名 .mmregs ;定义存储器映象寄存器STACK .usect “STACK”,10h ;分配10h个单元的堆栈空间 .bss a,4 ;为系数a分配4个单元的空间 .bss x,4 ;为变量x分配4个单元的空间 .bss y,1 ;为结果y 分配1个单元的空间 .def start ;定义标号start,12,(2)已初始化段,已初始化段是由.text、.data的.sect命
8、令建立,位置,包含有可执行代码或初始化数据,作用,通常将它们定位到EPROM区,使用方法,.text 段起点.data 段起点.sect “段名”,段起点,段程序计数器(SPC)定义的一个起始值。,程序员为自定义已初始化段起的名字,13,例4-1 编写计算y=a1*x1+a2*x2+a3*x3+a4*x4的汇编源程序* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * example.asm y=a1*x1+a2*x2+a3*x3+a4*x4 * * * * * * * * * * * * * * * * * * *
9、 * * * * * * * * * * * * * .title “example.asm” ;为汇编源程序取名 .mmregs ;定义存储器映象寄存器STACK .usect “STACK”,10h ;分配10h个单元的堆栈空间 .bss a,4 ;为系数a分配4个单元的空间 .bss x,4 ;为变量x分配4个单元的空间 .bss y,1 ;为结果y 分配1个单元的空间 .def start ;定义标号start .data ;定义数据代码段table: .word 1,2,3,4 ;在标号table开始的8个单元中 .word 8,6,4,2 ;为这8个单元赋初值,14,(3)段程序计
10、数器(SPC),编址过程,表示一个程序代码段或数据段的当前地址,作用,一开始,汇编器将每个SPC置0。当汇编器将程序代码或数据加到一个段内时,相应的SPC就增加。如果再继续对某个段汇编,则相应的SPC就在先前的数值上继续增加。链接器在链接时要对每个段进行重新定位。,15,(4).段定义举例列表文件,TMS320C54x COFF Assembler Version 3.70 Tue Oct 19 12:42:59 2004Copyright (c) 1996-2001 Texas Instruments Incorporatedexample.asm PAGE 1 1 * * * * * *
11、* * * * * * * * * * * * * * * * * * * * * * * * * * 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 00
12、0008 .bss y,1 ;为结果y 分配1个单元的空间 10 .global _c_int00 ;定义标号,列表文件中包括源程序语句和目标代码,Field 1源程序语句的行号,用十进制数表示,Field 2段程序计数器(SPC),用十六进制数表示,Field 4:源程序语句,16,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个单元赋初值 00
13、0005 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
14、+ ;重复传送 8个数据 000008 0000,源文件的每一行都会在列表文件中生成一行。包括行号、段程序计数器SPC的数值、汇编后的目标代码、源程序语句。,一条指令可以生成1或2个字的目标代码。,第2字单独列一行,列出了SPC的数值和目标代码 。,Field 3目标代码,17,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
15、 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源程序语句的行号,用十进制数表示,
16、Field 2段程序计数器(SPC),用十六进制数表示,Field 4:源程序语句,Field 3目标代码! 未定义的外部引用。 .text段重新定位。” .data段重新定位。+ .sect段重新定位。- .bss和.usect段重新定位。,18,例4-4 段命令应用举例:2 * * * * * * * * * * * * * * * * * * * * * * * * * * 3 * Assemble an initialized table into .data *4 * * * * * * * * * * * * * * * * * * * * * * * * * *5 0000 .d
17、ata6 0000 0011 coeff .word 011h,022h,033h 0001 0022 0002 00337 * * * * * * * * * * * * * * * * * * * * * * * * * *8 * * Reserve space in .bss for a variable * *9 * * * * * * * * * * * * * * * * * * * * * * * * * * 10 0000 .bss buffer,1011 * * * * * * * * * * * * * * * * * * * * * * * * * *12 * * sti
18、ll in .data * *13 * * * * * * * * * * * * * * * * * * * * * * * * * *14 0003 0123 ptr .word 0123h,(4)列表文件段定义举例,列表文件分析,有多少个段,如何排列,分别占空间多少,19,15 * * * * * * * * * * * * * * * * * * * * * * * * * *16 * * Assemble code into the .text section * *17 * * * * * * * * * * * * * * * * * * * * * * * * * *18 00
19、00 .text19 0000 100f add: LD 0Fh,A20 0001 f010 aloop: SUB #1,A 0002 0001 21 0003 f842 BC aloop,AGEQ 0004 000122 * * * * * * * * * * * * * * * * * * * * * * * * * *23 * * Another initialized table into .data * *24 * * * * * * * * * * * * * * * * * * * * * * * * * *25 0004 .data26 0004 00aa ivals .wor
20、d 0Aah,0BBh,0CCh 0005 00bb 0006 00cc,20,27 * * * * * * * * * * * * * * * * * * * * * * * * * * * * Define another section for more variables * * * * * * * * * * * * * * * * * * * * * * * * * * * *30 0000 var2 .usect “newvars”,131 0001 inbuf .usect “newvars”,732 * * * * * * * * * * * * * * * * * * *
21、* * * * * * *33 * * Assemble more code into .text * *34 * * * * * * * * * * * * * * * * * * * * * * * * * *35 0005 .text 0005 110a mpy: LD 0Ah,B 0006 f166 mloop: MPY #0Ah,B 0007 000a 0008 f868 BC mloop,BNOV 0009 0006 * * * * * * * * * * * * * * * * * * * * * * * * * * * * Define a named section for
22、int. vectors * * * * * * * * * * * * * * * * * * * * * * * * * * * * 0000 .sect “vectors” 0000 0011 .word 011h,033h 0001 0033,21,在此例中,一共建立了5个段:.text 段内有10个字的程序 代码。.data 段内有7个字的数据。vectors 是一个用.sect建 立的自定义段,段内 有2个字的已初始化数 据。.bss 在存储器中为变量保 留10个存储单元。newvars是一个用.usect命令 建立的自定义段,它 在存储器中为变量保 留8个存储单元。,22,2.
23、常数初始化伪指令,.bes和.space伪指令在当前段保留确定数目的位在.bes段中的标号指向保留位的第一个字在.space段中的标号指向保留位的最后一个字例如:RES_1.bes 20 RES_2.space 17,23,2. 常数初始化伪指令,.byte:把一个或多个8bits的值放入当前段中连续的字中.BYTE 0B8H,23H.int和.word把一个或多个16bits数存放到当前段的连续字中 .float和 .xfloat单精度(32bits)浮点数存放在当前段的连续字中,高位先存。.float能自动按域的边界排列,24,2. 常数初始化伪指令,.long和.xlong把32bits
24、数存放到当前段的连续字中。.long能够自动按长字边界排列,.xlong不能.string和.pstring把8bits的字符从一个或多个字符串中传送到当前段中,25,2. 常数初始化伪指令,.string类似于.byte。.pstring也是8bits宽度,但它是把两个字符打包成一个字,如果字符串没有占满最后一个字,剩下的加填零。以上伪指令是.struct/.endstruct序列的一部分时,它们不会对存储器进行初始化,只是定义各个成员的空间大小。,26,2. 常数初始化伪指令,.field伪指令:把一个数放入当前字的特定数目的位域中。使用.field可以把多个域打包成一个字。汇编器不会增加
25、SPC(段程序计数器)的值直至填满一个字。,27,5. 引用其它文件的伪指令,.copy/.include:告诉汇编器开始从其它文件中读源语句从.copy文件中读的语句会打印在列表中从.include文件中读的语句不会打印在列表中。例如: .include “tables.inc” .copy “filename.asm”,28,5. 引用其它文件的伪指令,.def :确认一个在当前模块中定义的且能被其它模块使用的符号.global:声明一个外部符号,使其它模块在连接时可以使用。.ref:确认一个在当前模块中使用但在其它段中定义的符号。.mlib向汇编器提供一个包含了宏定义的文档库的名称。,“
26、File1.asm” .global x,y,z .global init .end,“File2.asm” .def x,y,z .ref init .end,29,6. 条件汇编指令,.if/.elseif/.else/.endif告诉汇编器按照表达式值的条件汇编一块代码。.loop/.break/.endloop告诉汇编器按照表达式值的循环汇编一块代码。.loop标注一块循环代码的开始.break告诉汇编当表达式为假时,继续循环汇编;当表达式为真时,立刻转到.endloop后的代码。.endloop标注一个可循环块的末尾。,30,4.6 宏定义和宏调用,(1)两者都可以被多次调用,但是把
27、子程序汇编成目标代码的过程只进行一次,而在用到宏指令的每个地方都要对宏指令中的语句逐条地进行汇编。(2)在调用前,由于子程序不使用参数,故子程序所需要的寄存器等都必须事先设置好;而对于宏指令来说,由于可以使用参数,调用时只要直接代入参数就行了。 (3)宏指令可以在源程序的任何位置上定义,但必须在用到它之前先定义好。宏定义可以嵌套。,宏指令与子程序的异同,31,macname .macroparameter 1,parameter n 助记符指令与宏指令 .mexit .endm,宏定义的格式,宏调用的格式,label:macname parameter1,parametern,32,1 *23
28、 * add34 *5 * ADDRP=P1+P2+P3 ;说明宏功能67 add3 .macro p1,p2,p3,ADDRP ;定义宏89 LD p1,A ;将参数1赋给A10 ADD p2,A ;将参数2与A相加11 ADD p3,A ;将参数3与A相加12 STL A,ADDRP ;将结果A的低字存参数413 .endm ;结束宏141516 .global abc,def,ghi,adr ;定义全局符号1718 000000 add3 abc,def,ghi,adr ;调用宏11 000000 1000! LD abc,A ;宏展开1 000001 0000! ADD def,A 1
29、 000002 0000! ADD ghi,A1 000003 8000! STL A,adr,例4-2 宏定义、宏调用和宏展开的一个例子。,33,4.7 目标文件的链接,链接器主要功能,根据链接命令或链接命令文件(.cmd文件),将一个或多个COFF目标文件链接起来,生成存储器映象文件(.map)和可执行的输出文件(.out)(COFF目标模块),34,1运行链接程序,(1)键入命令 lnk500 (2)键入命令lnk500 file1.obj file2.obj o(3)键入命令 lnk500 linker.cmd,链接器是名为lnk500.exe 的可执行程序,2链接器选项,应包含如下内
30、容:file1.objfile2.obj-o lind.out,建立一个名为a.out(默认情况)的可重新定位的输出模块。,35,3.链接器对段的处理,(1)把一个或多个COFF目标文件中的各种段作为链接器的输入段,经链接后在一个可执行的COFF输出模块中建立各个输出段。(2)为各个输出段选定存储器地址。,链接器在对段进行处理时,主要完成,汇编器在需要引用重新定位的符号处都留了一个重定位入口。链接器对符号重定位时,利用这些入口修正对符号的引用值。,36,(1)将各个段定位到存储器分配图中,这样一来每个段都从一个恰当的地址开始。(2)将符号的数值调整到相对于新的段地址的数值。(3)调整对重新定位
31、后符号的引用。汇编器在需要引用重新定位的符号处都留了一个重定位入口。链接器对符号重定位时,利用这些入口修正对符号的引用值。,37,链接器将输入段组合成一个可执行的目标模块,2018年4月21日,DSP原理及应用,38,默认的存储器分配过程:,.text,.text1,.text2,.data,.data1,.data2,.bss,.bss1,.bss2,table,table_1,table_2,u_vars1,u_vars1,u_vars2,FFT,FFT,没有使用,没有配置,没有配置,没有使用,39,例4-5 列表文件中,汇编器为需要重新定位的符号所留的重定位入口。1 0100 X .se
32、t 0100h ;给X赋值2 0000 .text3 0000 FO73 B Y ;生成一个重定位入口 0000 00044 0002 F020 LD #X,A ;生成一个重定位入口 0003 0000!5 0004 F7E0 Y: RESET,在.text段对X的引用是一次外部引用,40,假设链接时X重新定位在地址7100h,.text段重新定位到从地址7200h开始,那么Y的重定位值为7204h。链接器利用两个重定位入口,对目标文件中的两次引用进行修正: f073 B Y 变成 f073 0004 7204 f020 LD #X,A 变成 f020 0000! 7100在COFF目标文件中
33、有一张重定位入口表。链接器在处理完之后就将重定位入口消去,以防止在重新链接或加载时再次重新定位。,一个没有重定位入口的文件称为绝对文件,它的所有地址都是绝对地址。,41,4.链接器命令文件,(1)将有多个选项的命令,写成一个链接器命令文件.cmd。 (2)运行链接器命令文件.cmd,生成一个映象文件.map和一个可执行的输出文件.out (3)进行存储器分配,主要功能,使用方法,lnk500链接器命令文件名.cmd,42,例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=0100hSECTIONS /* SECTIONS 命令 */.text: ROM.data: ROM.bss: RAM,如果链接器认定一个文件为目标文件,就对它链接;否则就假定它是一个命令文件,并从中读出命令和进行处理。,