好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

第4章汇编语言程序的开发工具.ppt

123页
  • 卖家[上传人]:m****
  • 文档编号:589571587
  • 上传时间:2024-09-11
  • 文档格式:PPT
  • 文档大小:569.50KB
  • / 123 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 第4章汇编语言程序的开发工具2021/8/61 知识要点:本章介绍了TMS320C54x软件开发流程、汇编语言程序的编写、编译和链接过程,重点介绍了COFF段的一般概念、汇编器和链接器处理段的方法以及程序的重定位方法等2021/8/62 4.1 TMS320C54x软件开发流程 ’C54x的应用软件开发主要完成以下的工作: 首先是选择编程语言编写源程序’C54x提供两种编程语言:汇编语言和C/C++语言 当源程序编写好后,选择开发环境, ’C54x提供了两种开发环境一种是非集成开发环境,如图4.1.1另一种是集成开发环境,简称CCSCCS在Windows操作系统下运行,它集成了非集成开发环境的所有功能,并扩展了许多其他的功能在后面的章节中会有介绍2021/8/63 2021/8/64 如果源程序是C/C++语言,需调用’C54x的C编译器将其编译成汇编语言,并送入’C54x的汇编器进行汇编对于用汇编语言编写的程序则直接送给汇编器进行汇编,汇编后产生COFF格式的目标文件,再用链接器进行链接,生成在’C54x可执行的COFF格式的目标代码,并利用调试工具对可执行的目标代码进行调试。

      2021/8/65 对’C54x应用程序的开发提供以下几个开发调试工具: ◇ C/汇编语言源码调试器与软件仿真器、评价模块、软件开发系统、软件模拟器等开发工具配合使用 ◇ 软件仿真模拟器 ◇集成开发环境CCS ◇ DSK ◇ 软件开发系统SWDS ◇可扩展的开发系统仿真器(XDS510) ◇评价模块(EVM板) 2021/8/66 4.2 汇编语言程序的编辑、汇编和链接过程 汇编语言源程序可以在任何一种文本编辑器中进行当汇编语言源程序完成后,还必须经过汇编和链接后才能进行 下图给出了汇编语言程序的编辑、汇编和链接过程: 文本编辑器汇编器链接器调试程序.cmd链接命令文件.lst列表文件转换程序.asm源文件.obj目标文件.out输出文件-l-m.map存储器映像文件2021/8/67 ① 编辑 利用各种文本编辑器,如记事本、WORD、EDIT等,可编写汇编语言源程序 ② 汇编 当汇编语言源程序编写好以后,可利用’C54x的汇编器ASM500,对一个或多个源程序进行汇编,生成.lst文件和.obj文件。

      常用汇编命令为: asm500 %1 -s -l -x2021/8/68 ③ 链接 链接就是利用’C54x的链接器LNK500,根据链接器命令文件(.cmd)对已汇编过的一个或多个目标文件(.obj)进行链接,生成存储器映像文件(.map)和输出文件(.out) 常用链接命令为 lnk500 %1.cmd2021/8/69 ④ 调试 对输出文件(.out)调试可以采用多种手段,现介绍如下: ◆软件仿真器进行调试 ◆硬件仿真器进行调试 ◆评价模块进行调试 ⑤ 固化用户程序 调试完成后,利用HEX500格式转换器对ROM编程,或对EPROM编程,最后安装到用户的的应用系统中2021/8/610 4.3 COFF的一般概念 汇编器和链接器生成的目标文件,是一个可以由’C54x器件执行的文件这些目标文件的格式称为公共目标文件格式(Common Object File Format, 缩写为COFF) COFF采用代码段和数据段的形式,因此便于模块化的编程。

      2021/8/611 4.3.1 COFF文件的基本单元 COFF文件有3种类型:COFF0、COFF1、COFF2每种类型的COFF文件的标题格式都有所不同,但数据部分却是相同的 段是COFF文件中最重要的概念每个目标文件都分成若干段 段是在存储器图中占据相邻空间的代码或数据块2021/8/612 所有的COFF目标文件都包含以下3种形式段: ◆ .text段,通常包含可执行代码; ◆ .data段,通常包含初始化数据; ◆ .bss段,通常为未初始化变量保留存储空间 此外,汇编器和链接器可以建立、命名和链接自定义段这种自定义段是程序员自已定义的段,使用起来与.data、.text、及.bss段类似它的好处是在目标文件中与.data、.text、及.bss分开汇编,链接时作为一个单独部分分配到存储器中2021/8/613 COFF目标文件有以下两种基本类型的段 ① 初始化段 初始化段中包含有数据或程序代码包括: ◆ .text段是已初始化段; ◆ .data段是已初始化段; ◆ .sect汇编器伪指令建立的自定义段也是已初始化段。

      2021/8/614 ② 未初始化段 在存储空间中,它为未初始化数据保留存储空间包括: ◆ .bss段未初始化段; ◆ .usect汇编命令建立的自定义段也是未初始化段2021/8/615 链接器的一个任务就是分配存储单元,即把各个段重新定位到目标存储器中,如下图: 2021/8/616 链接器的功能之一是将目标文件中的段重新定位到目标系统的存储器中,该功能称为定位或分配 大多数系统都包含有几种存储器,通过对各个段的重新定位,可以使目标存储器得到更加有效的利用2021/8/617 4.3.2 汇编器对段的处理 汇编器对段的处理是通过段伪指令来区别各个段,并将段名相同的语句汇编在一起汇编器有5条命令可识别汇编语言程序的各个部分这5条命令是: ◆ .bss(未初始化段) ◆ .usect(未初始化段) ◆ .text(已初始化段) ◆ .data(已初始化段) ◆ .sect(已初始化段)2021/8/618 ① 未初始化段 .bss和.usect命令生成未初始化段未初始化段就是’C54x存储器中的保留空间,通常将它们定位到RAM区。

      在目标文件中,这些段没有确切的内容;在程序运行时,可以利用这些存储空间存放变量 这两条命令句法如下: .bss符号,字数 .usect“段名”,字数2021/8/619 符号—对应于保留的存储空间第一个字的变量名称,可让其它段引用,也可以定义为全局符号; 字数—表示在.bss段或标有名字的段中保留多少个存储单元; 段名—程序员为自定义未初始化段起的名字② 已初始化段 .text、.data和.sect命令生成已初始化段已初始化段中包含有可执行代码或初始化数据这些段中的内容都在目标文件中,当加载程序时再放到’C54x的存储器中每一个已初始化段都是可以重新定位的,并且可以引用其他段中所定义的符号2021/8/620 3条初始化命令的句法如下: .text[段起点] .data[段起点] ·sect“段名”[,段起点] 其中,段起点是任选项如果选用,它就是为段计数器(SPC)定义的一个起始值如果默认,则SPC从0开始当汇编器遇到.text、.data和.sect命令时,将停止对当前段的汇编,然后将紧接着的程序代码或数据汇编到指定段中,直到再遇到另一条.text、.data和.sect命令为止。

      2021/8/621 当汇编器遇到.bss或.usect命令时,并不结束当前段的汇编,只是暂时从当前段脱离出来,并开始对新的段进行汇编 段的构成要经过一个反复的过程2021/8/622 ③ 命名段 命名段由用户指定,与默认的.text,.data和.bss段的使用相同,但它们被分开汇编 例如,重复使用.text段建成单个.text段,在链接时,这个.text段被作为单个单元定位 2021/8/623 假如不希望一部分可执行代码和.text段分配在一起,可将它们汇编进一个命名段,这样就可定位在与.text段不同的地方,也可将初始化的数据汇编到与.data段不同的地方,或者将未初始化的变量保留在与.bss段不同的位置此时,可用以下两个产生命名段的伪指令: .usect伪指令产生类似.bss段,为变量在RAM中保留存储空间 .sect伪指令产生类似.text和.data段,可以包含代码和数据 .sect伪指令产生地址可重新定位的命名段2021/8/624 这两个伪指令的使用句法为: 符号.usect “段名”,字数 .sect “段名” 可以产生多达32767不同的命名段。

      不同的伪指令不能使用相同的名字,也就是说,不能用.usect 创建命名段,然后用.sect 再创建一个相同名字的段2021/8/625 ④ 子段 子段是较大段中的小段 链接器可以像处理段一样处理子段子段结构可用来对存储器间进行更紧凑的控制,可以使存储器图更加紧密 子段的命名的句法为: 基段名:子段名 例如,若要在.text段内建立一个称之为_func的子段,可以用如下的命令: .sect“.text: _func”2021/8/626 ⑤ 段程序计数器(SPC) 汇编器为每个段都安排了一个单独的程序计数器——段程序计数器,简称SPC SPC表示一个程序代码或数据段内当前的地址开始时汇编器将每个SPC置0当汇编器将程序代码或数据加到一个段内时,相应的SPC就增加如果再继续对某个段汇编,则相应的SPC就在先前的数值上继续增加链接器在链接时要对每个段重新定位 2021/8/627 下例列出的是一个汇编语言程序汇编后的.lst文件lst文件由4个部分组成,即 第一部分(Field1):源程序行号 第二部分(Field2):段程序计数器 第三部分(Field3):目标代码 第四部分(Field4):源程序2021/8/628 50000 .data60000 0044 coeff .word044h,055h,066h0001 00550002 0066100000.bss buffer, 8140003 0456 prt .word0456h180000.text190000100dadd:LD0Dh,A200001f010aloop:SUB#1, A00020001210003f842BCaloop, AGEQ2500040001’0004.data000400ccivals.word0CCh,0DDh,0EEh000500dd000600ee2021/8/629 300000var2 .usect“newvars”, 2310001inbuf .usect“newvars”, 8350005 text360005110a mpy:LD0Ah,B370006f166 mloop: MPY#0Ah,B0007000a380008f86800090006’420000 .sect “vectors”4300000044 .word 044h, 088h44000100882021/8/630 在此例中,共建立了5个段: ◆.text段内有10个字的程序代码 ◆.data段内有7个字的数据 ◆ vectors是一个用.sect命令生成的自定义段,段内有2个字的已初始化数据 ◆.bss在存储器中为变量保留8个存储单元 ◆.newvars是一个用.usect命令建立的自定义段,它在存储器中为变量保留10个存储单元。

      2021/8/631 在此例中 建立的5个段如图4.3.2 2021/8/632 4.3.3 链接器对段的处理 链接器是开发TMS320C54x器件必不可少的开发工具,它对段处理时有两个任务: 其一是将一个或多个COFF目标文件中的各种段作为链接器的输入段,经链接后在一个执行的COFF输出模块中建立各个输出段; 其二是为各个输出段选定存储器地址2021/8/633 链接器有2条伪指令支持上述任务 ◆MEMORY伪指令 用来定义目标系统的存储器分配空间,包括对存储器各部分命名,及规定它们的起始地址和长度 ◆SECTIONS伪指令 它告诉连接器如何将输入段组合成输出段,及将输出段放在存储器中的什么位置 2021/8/634 ① 默认的存储器分配 书图4.3.3说明了两个文件的链接过程 4.3.3 两个文件的链接过程2021/8/635 图4.3.3中,链接器对目标文件file1.obj和file2.obj进行链接。

      每个目标文件中,都有.text、.data和.bss段,此外还有自定义段 链接器将两个文件的.text段组合在一起,以形成一个.text段,然后再将两个文件的.data段和.bss段以及最后自定义段组合在一起2021/8/636 ② 段放入存储器空间 图4.3.3说明了链接器结合段的默认方法,有时希望采用其他的结合方法 例如,可能不希望将所有的.text段结合在一起形成单个的.text段,或者希望将命名段放在.data的前面 若希望将段放在指定类型的存储器中,此时可采用MEMORY和SECTIONS伪指令2021/8/637 4.3.4 链接器对程序的重新定位 ① 链接器重新定位 汇编器处理每个段都是从地址0开始,而所有需要重新定位的符号(标号)在段内都是相对于地址0的 事实上,所有段都不可能从存储器中地址0单元开始,因此链接器必须通过以下方法对各个段进行重新定位:2021/8/638 ◆ 将各个段定位到存储器空间中,这样一来每个段都能从一个恰当的地址开始; ◆将符号变量调整到相对于新的段地址的位置; ◆将引用调整到重新定位后的符号,这些符号反映了调整后的新符号值。

      2021/8/639 汇编器在需要引用重新定位的符号处都留了一个重定位入口链接器在对符号重新定位时,利用这些入口修正对符号的引用值下面举例说明:1 .refX ;符号X、Y、Z需要重新定位2.refZ ;X、Z是在另一个模块中定义的30000.text ;Y是在这个模块的.text段定义的40000 F073BY ;产生一个重新定位入口 0001 0006’ ;Y的值为6,X和Z值为050002 F073BZ ;产生一个重新定位入口 0003 0000!60004 F020LD#X,A ;产生一个重新定位入口 0005 0000!70006 F7E0Y:RESET2021/8/640 假设链接时X重新定位地址7100H, .text段重新定位到从地址7200H开始,那么Y的重新定位值为7204H。

      链接器利用重定位入口,对目标文件中的两次引用进行修正f073 B Y 变成 f0730004’ 7204’ f020 LD #X, A 变成 f020 0000’ 7100② 运行时间重新定位 有时,希望将代码装入存储器的一个地方,而在另一个地方运行 2021/8/641 例如一些关键的执行代码必须装在系统的ROM中,但希望在较快的RAM中运行,链接器提供了一个处理该问题的简单方法,利用SECTIONS伪指令选项可让链接器定位两次,第一次使用装入关键字设置装入地址,再使用运行关键字设置它的运行地址 如果只为段提供一次定位,则该段将只定位一次,并且装入和运行地址相同 未初始化的段(例如.bss)不能装入,所以它仅有的有意义的地址为运行地址,链接器只对没有初始化的段定位一次。

      2021/8/642 4.3.5 程序装入 链接器产生可执行的COFF目标文件可执行的目标文件模块与链接器输入的目标文件具有相同的COFF格式,但在可执行的目标文件中,对段进行结合并在目标存储器中进行重新定位 为了运行程序,在可执行模块中的数据必须传输或装入目标系统存储器2021/8/643 有两种方法可以用来装入程序,选哪种方法取决于执行环境 ◆TMS320C54x调试工具包括软件模拟器、XDS仿真器和集成系统CCS它们都具有内部装入器,包含调用LOAD命令装入器读取可执行文件,将程序复制到目标系统的存储器中 ◆采用Hex转换工具例如Hex500,将可执行COFF目标模块转换成几种其他目标格式文件,然后将转换后的文件写入EPROM2021/8/644 4.3.6 COFF文件中的符号 COFF文件中有一个符号表,主要用来存储程序中有关符号的消息,链接时对符号进行重新定位要用到该表,调试程序也要用到它2021/8/645 ① 外部符号 外部符号,是在一个模块中定义、又可以在另一个模块中引用的符号。

      可以用伪指令.def、.ref或.global来定义某些符号为外部符号 ◆.def指令在当前模块中定义,并可在别的模块中使用的符号 ◆ .ref指令在当前模块中使用在别的模块中定义的符号 ◆ .global指令可以是上面的任何一种情况2021/8/646 例:以下的代码段说明上面的定义 x:ADD#56h,A By .def x .ref y 汇编时,汇编器把x和y都放在目标文件的符号表中当这个文件与其它目标文件链接时,遇到x,就定义了其它文件不能识别的x, 同样遇到符号y时,链接器就检查其他文件对y的定义总之链接器必须使所引用的符号与相应的定义相匹配2021/8/647 ② 符号表 每当遇到一个外部符号,汇编器都将符号表中产生一个条目汇编器还产生一个指到每段的专门符号,链接器使用这些符号来对其他符号重新定位2021/8/648 4.4 源程序的汇编 汇编器的作用是将汇编语言源程序转换成机器语言目标文件这些目标文件都是公共目标文件格式(COFF) 汇编语言源程序文件包括汇编命令、汇编语言指令和宏指令。

      汇编命令用来控制汇编的过程,包括列表格式、符号定义和将源代码放入块的方式等2021/8/649 汇编器包括如下功能: ① 将汇编语言源程序汇编成一个可重新定 位的目标文件; ② 根据需要,可以生成一个列表文件,并 对该列表进行控制; ③ 将程序代码分成若干个段,每个段的目 标代码都有一个SPC管理; 2021/8/650 ④ 定义和引用全局符号,如果需要可以在 列表文件后面附加一张交叉引用表; ⑤ 对条件程序块进行汇编; ⑥ 支持宏功能,允许定义宏命令; ⑦ 为每个目标代码块设置一个程序计数器 SPC2021/8/651 4.4.1 汇编程序的运行 ’C54x的汇编程序名为asm500.exe 要运行汇编程序,可输入如下命令: asm500 [input file[ object file [listing file]]] [-options]input file—汇编源文件名,默认扩展名.asm。

      object file—汇编程序生成的目标文件objlisting file— 汇编程序生成的列表文件lst-options — 汇编器使用的各种选项,表4.4.12021/8/652 4.4.2 汇编时的列表文件 汇编器对源程序汇编时,如果采用-l选项,汇编后将产生一个列表文件 列表文件中包括源程序语句和目标代码 下面是一个列表文件的例子,用来说明它的各部分的内容2021/8/653 1.global RESET,INT0,INT1,INT22.global TINT,RINT,XINT,USER3.global ISR0, ISR1, ISR24.global time, rcv, xmt, proc5 6 Initmac .macro7*initialize macro8 SSBX OVM9 LD #0, DP10 LD #7, ARP11 LD #037h, A12 RSBX INTM13 .endm14 ****************************** 15 * 复位中断向量复位中断向量16 ******************************17000000.sect “reset”18000000 F073 RESET: B init19 000001 0008+19000002 F073 INT0: B ISR020 000003 0000!20000004 F073 INT2: B ISR121 000005 0000!21000006 F073 INT2: B ISR222 000007 0000!2322 2423*24000000 .sect “ints”25000000 F073 TINT B time26 000001 0000!26000002 F073 XINT B rcv27 000003 0000!27000004 F073 XINT B xmt28 000005 0000!28000006 F073 USER B proc29 000007 0000!3029 **********************3130 * 初始化处理器初始化处理器3231 **********************2021/8/654 32000008 init: initmac331 *initialize macro341000008F7B9SSBXOVM351000009EA00LD #0, DP36100000aF4A7LD #7, ARP37100000bE837LD #37H, A38100000cF6BBRSBXINTM︸︸行行号号SPC目标代码源程序语句2021/8/655 如例所示,列表文件可以分成4个部分。

      ◆ Field1:源程序语句的行号码,用十进制数表示 ◆ Field2:段程序计数器,用十六进制表示 ◆ Field3:目标代码,用十六进制表示 后面的记号表示在链接时需要重新定位 未定义的外部引用 ’ : .text段重新定位 ” : .data段重新定位 + : .sect段重新定位 - : .bss和.usect段重新定位◆ Field4:源程序语句2021/8/656 4.4.3 汇编伪指令 汇编伪指令用于为程序提供数据并指示汇编程序如何汇编源程序,是汇编语言程序的一个重要内容 2021/8/657 汇编伪指令可完成以下工作: ◆ 将代码和数据汇编进指定的段; ◆ 为未初始化的变量在存储器中保留空间; ◆ 控制清单文件是否产生; ◆ 初始化存储器; ◆ 汇编条件代码块; ◆ 定义全局变量; ◆ 为汇编器指定可以获得宏的库; ◆ 考察符号调试的信息2021/8/658 ’C54x汇编器共有64条汇编伪指令,根据他们的功能,可以将其分成8类: ① 对各种段进行定义的命令,如.bss、.data等 ② 对常数(数据和存储器)进行初始化的命令, 如.bes、byte、.field、float等 ③ 调整SPC(段寄存器),如.align ④ 对输出列表文件格式化的命令,如.drlist ⑤ 引用其他文件的命令,如copy ⑥ 控制条件汇编的命令,如.break ⑦ 在汇编时定义符号的命令,如.asg ⑧ 执行其他功能的命令,如.algebraic2021/8/659 ① 定义段的伪指令 定义段的伪指令用于定义相应的汇编语言程序段。

      表4.4.2列出了定义段的伪指令的助记符以及语法格式和注释•.text — 此段存放程序代码•.data — 此段存放初始化了的数据•.bss — 此段存入未初始化的变量•.sect '名称' — 定义一个有名段,放初始化了的数据或程序代码2021/8/660 例4.4.2以实例说明如何应用定义段的伪指令 该例是一个输出清单文件,第一列为行号,第二列位SPC的值,每段有它自己的SPC当代码第一次放在段中时,其SPC等于0在其他的代码段被汇编后,若继续将代码汇编进该段,则它的SPC继续计数,就好像没有受到干扰2021/8/661 例4.4.2中伪指令执行以下任务: ◆ .text初始化值为1,2,3,4,5,6,7,8的字; ◆ .data初始化值为9,10,11,12,13,14,15,16 var_defs初始化值为17,18字 ◆ .bss保留19个字的空间 ◆ .usect保留20个字的空间 ◆ .bss和.usect伪指令既不结束当前的段也不开始新段,它们保留指定数量的空间,然后汇编器开始将代码或数据汇编当前的段2021/8/662 1234000000.text5000000 0001.word 1,26 000001 00026000002 0003.word 3,47 000003 00048798109111011000000.data12000000 0009.word 9,1013 000001 000A13000002 000B.word 11,1214 000003 000C1514161517161817191819000000.sect “var_defs”2020 000000 0011 .word 17,1821 000001 0012222123222423252425000004.data26000004 000D.word 13,1427 000005 000E27000000.bss sym, 1928000006 000F.word 15,1629 000007 0010302931303231333233 000004 .text34 000004 0005.word 5,635 000004 000635000000 usym.usect “xy”, 2036000006 0007 .word 37000007 00082021/8/663 ② 初始化常数的伪指令 初始化常数的伪指令为当前段的汇编常数值。

      表4.4.3列出了初始化常数的伪指令的助记符以及语法格式和注释 .byte value1[,…valuen]初始化当前段里的一个或多个连续字,每个值的宽度限制为8位field value[,size in bits ]初始化一个可变长度的域,将单个值放入当前字的指定位域中word value1[,…valuen]初始化一个或多个16位整数,即把16位的值放到当前段的连续字中long value1[,…valuen]初始化一个或多个32位整数,即把32位的值放到当前段的2个连续字中2021/8/664 例4.4.3 图4.4.1比较了.byte,.int,.long,.xlong,.float,.xloat,.word, .string指令见p1172021/8/665 在这个例子中假定已经汇编了以下的代码: 1000000 00aa.byte0AAh, 0BBh2 000000 00bb2000002 0ccc.word0CCCh3000003 0eee.xlong0EEEEFFFh4000004 efff4000006 eeee.long0EEEEFFFFh5000007 ffff5000008 dddd.int0DDDDh6000009 3fff.xfloat1.9999997 00000a ffac700000c 3fff.float1.999999800000d ffac800000e 0068900000f 006510000010 006c11000011 00702021/8/666 ③ 对准段程序计数器的伪指令 对准段程序计数器的伪指令包括:.align伪指令和.even伪指令。

      表4.4.4列出了对准段程序计数器的伪指令的助记符以及语法格式和注释 伪指令助记符及格式伪指令助记符及格式 描述描述.align.even用于将段程序计数器对准在用于将段程序计数器对准在1~128字的边界字的边界用于使用于使SPC指到下一个字的边界指到下一个字的边界表4.4.4 对准段程序计数器的伪指令2021/8/667 ⑴ .align伪指令的操作必须是在20~216之间且等于2的幂例如: 操作数为1时,对准SPC到字的边界; 操作数为2时,对准SPC到长字/偶字的边界; 操作数为128时,对准SPC到页面的边界; 没有操作数时,.align伪指令默认为页面边界 2021/8/668 ⑵ .even伪指令等效于指定.align伪指令的操作数为1的情形当.even操作数为2时,将SPC对准到下一个长字的边界任何在当前字中没有使用的位都填充0.2021/8/669 图4.4.2说明了.align伪指令的使用情况 2021/8/670 假定汇编了以下的代码: 1000000 4000.field 2,32000000 4160.field 11,83 .align 24000002 0045 .string “Errorcnt”5000003 00726000004 00727000005 006f8000006 0072 9000007 006310000008 006e11000009 0074125.align5000080 0004.byte 42021/8/671 ④ 格式化输出清单文件的伪指令 格式化输出清单文件的伪指令用于格式化输出清单文件,如表4.4.5 2021/8/672 ⑤ 引用其他文件的伪指令 引用其他文件的伪指令为引用其他文件提供信息。

      如表4.4.6: 2021/8/673 ⑥ 条件汇编伪指令 条件汇编伪指令用来通知汇编器按照表达式计算出的结果的真假,决定是否对某段代码进行汇编有两组伪指令用于条件代码块的汇编: ⑴ .if/.elseif/.else/.endif伪指令用于通知汇编器按照表达式的计算结果,对某段代码块进行条件汇编 ⑵ .loop/.break/.endloop伪指令用于通知汇编器按照表达式的计算结果重复汇编一个代码块2021/8/674 条件汇编伪指令的助记符及语法格式见表4.4.7: 2021/8/675 ⑦ 定义宏的伪指令 常用的定义宏的伪指令如表4.4.8: 2021/8/676 ⑧ 汇编时间符号伪指令 汇编时间符号伪指令用于使符号名与常数值或字符串等价起来 汇编时间符号伪指令如表4.4.9: 2021/8/677 .struct/.endstruct伪指令允许将信息组织到结构体中,以便将同类的元素分在一组然后由汇编器完成结构体成员偏离地址的计算 .struct/.endstruct伪指令不分配存储器,只是简单地产生一个可重复使用的符号模板。

      .tag将结构体与一个标号联系起来,.tag伪指令不分配存储器,且结构体的标记符必须使用之前先定义好2021/8/678 例 .struct/.endstruct伪指令举例 1 REAL_REC .struct; 结构体标记 20000 NOM .int; member1=0 3 0001 DEN .int; member2=1 4 0002 REAL_LEN .endstruct;real_len=2 5 6 000000 0001- ADD 7 ;访问结构体成员 8 9 000000.bss REAL,REAL _LEN REAL+REAL_REC.DEN,A2021/8/679 .union/.endunion伪指令通过创建符号模板,提供在相同的存储区域内管理多种不同的数据类型方法union不分配任何存储器,它允许类型和大小不同的定义临时存储在相同存储器空间2021/8/680 例 .union/.endunion伪指令举例 1.global employid 2 xample .union ;union标记 3 0000 ival .word ;menber1=int 4 0000 fval .float ;menber2=float 5 0000 sval .string ;menber3=string 6 0002 real_len .endunion ; real_len=2 7 8 000000 .bss emplyid,real_len ;指定空间 9 10 employid .tag xample ;声明结构实例 11 000000 0000- ADD emplyid.fval,A ;访问union成员2021/8/681 ⑨ 混合伪指令 书中表4.4.10列出了常用的混合伪指令: 2021/8/682 .newblock伪指令用于复位局部标号。

      局部标号是形式为$n或name?的符号当它们出现在标号域时被定义局部标号可用作跳转指令的操作数newblock伪指令通过在它们被使用后将它们复位的方式来限制局部标号的使用范围2021/8/683 4.4.4 宏定义和宏调用 ’C54x汇编器支持宏指令语言 利用宏指令,可以使源程序变得简短 宏的使用以下3个步骤 ① 定义宏有两种方法定义宏: ◆ 可在源文件的开始定义宏,或者在.include/.copy的文件中定义 ◆ 在宏库中定义 ② 调用宏 ③ 扩展宏 2021/8/684 宏指令与子程序一样,都是重复执行某一段程序,但两者是有区别的,有以下两点: ① 宏指令和子程序都可以被多次调用,但是把子程序汇编成目标代码的过程只进行一次,而在用到宏指令的每个地方都要对宏指令中的语句逐条地进行汇编 ② 在调用之前,由于子程序不使用参数,故子程序所需要的寄存器等都必须事先设置好,而对于宏指令来说,由于可以使用参数,调用时只要直接代入参数就行了2021/8/685 宏定义格式如下: macname .macro[parameter 1][,…,parameter n] model statements or macro directives [.mexit] .endm2021/8/686 宏调用格式如下: [label][:] macname [parameter 1][,…,parameter n]2021/8/687 例4.4.7 宏定义、宏调用和宏展开举例 1 * 2 3 * add3 4 * 5 *ADDRP=P1+P2+P3 6 7 add3.macroP1,P2,P3,ADDRP 8 9 LD P1,A 10 ADD P2,A 11ADD P3,A2021/8/688 12 STL A,ADDRP 13.endm 14 15 16.global abc,def,ghi,adr 17 000000 add3 abc,def,ghi,adr1 000000 1000! LD abc,A1 000001 0000! ADD def,A1 000002 0000! ADD ghi,A1 000004 8000! STL A,adr2021/8/689 4.5 链接器的使用 链接器的主要任务是:根据链接命令文件,将一个或多个COFF目标文件链接起来,生成存储器映像文件和可执行的输出文件,如下图: LNK500链接命令或链接命令或链接命令文件链接命令文件(.cmd文件文件)存储器存储器映像文件映像文件((.map文件)文件)一个或一个或多个目标文件多个目标文件((.out文件)文件)可执行可执行输出文件输出文件((.out文件)文件)2021/8/690 在链接过程中,链接器将各个目标文件合并起来,并完成以下工作: ◆ 将各个段配置到目标系统的存储器。

      ◆ 对各个符号和段进行重新定位,并给它们指定一个最终的地址 ◆ 解决输入文件之间未定义的外部引用2021/8/691 4.5.1 链接器的运行 ① 运行链接程序 ’C54x的链接器名为lnk500.exe 运行链接器有三种命令: lnk500 lnk500 file1.obj file2.obj -o link.out lnk500 linker.cmd说明:⒈使用第一种命令时,链接器会提示有关信息2021/8/692 ⒉使用第二种命令时,链接器是以file1.obj 和file2.obj 为目标文件进行链接,生成一个名为link.out的可执行输出文件⒊使用第三种命令时,需将链接的目标文件、连接选项以及存储器配置要求等编写到链接命令文件linker.cmd中 以第二种命令为例,链接命令文件 linker.cmd应包含如下内容 file1.obj file2.obj -o link.out② 链接器选项 表4.5.1列出了常用’C54x链接器选项在链接时,一般通过链接器选项(如-o)控制连接器操作2021/8/693 4.5.2 链接器命令文件的编写与使用 链接命令文件是将链接的信息放在一个文件中,这在多次使用同样的链接信息时,可以方便调用。

      在命令文件中可使用两个十分有用的伪指令MEMORY和SECTIONS,用来指定实际应用中的存储器结构和地址的映射2021/8/694 在命令行中不能使用这两个伪指令,命令文件都是ASCⅡ文件,可包含以下内容: ① 输入文件名,用来指定目标文件、存档库或其他命令文件 ② 链接器选项,它们在命令文件中的使用方法与在命令行中相同 ③ MEMORY和SECTIONS链接伪指令, MEMORY用来指定目标存储器结构,SECTIONS用来控制段的构成与地址分配 ④ 赋值说明,用于给全局符号定义和赋值2021/8/695 对于如下链接器命令: lnk500 a.obj b.obj -m prog.map -o prog.out 可以将上述命令行中的内容写成一个链接器命令文件link.cmd,内容如下: a.obj/*第一个输入文件名*/ b.obj /*第二个输入文件名*/ -m prog.map /*指定map文件的选项*/ -o prog.out /*指定输出文件的选项*/2021/8/696 执行链接器命令: lnk500link.cmd 就可以将两个目标文件a.obj和b.obj链接起来,并生成一个映像文件prog.map和一个可执行的输出文件prog.out,其效果与前面带-m和带-o选项的链接器命令完全一样。

      2021/8/697 例 链接器命令文件举例 a.obj b.obj /*输入文件名*/ -o prog.out /*指定输出文件的选项*/ -m prog.map /*指定map文件的选项*/ MEMORY /*MEMORY 伪指令*/ { PAGE 0: ROM: orgin=1000h, length=0100h PAGE 1: RAM: orgin=0100h, length=0100h } SECTIONS /*SECTIONS伪指令*/ { .text : >ROM .data : >ROM .bss : >RAM }2021/8/698 链接器命令文件都是ASCⅡ码文件,由上例可见,主要包含如下内容: ① 输入文件名,就是要链接的目标文件和文档库文件,或者是其他的命令文件 ② 链接器选项,这些选项既可以用在链接命令行,也可以编在命令文件中。

      ③ MEMORY和SECTIONS都是链接器命令,MEMORY命令定义目标存储器的配置,SECTIONS命令规定各个段放在存储器的什么位置 2021/8/699 4.5.3 目标库 目标库是包含完全目标文件作为成员的存档文件 通常将一组有关的模块组合在一起形成一个库使用目标库可减少链接的时间和可执行模块的长度 指定库的次序是很重要的,因为链接器在搜索库时仅仅包括那些具有可用来分辨没有定义的符号的成员2021/8/6100 下面是链接几个文件和库的例子,假设: ① 输入文件f1.obj和f2.obj均引用了一个名为clrscr的外部函数; ② 输入文件f1.obj引用了符号origin; ③ 输入文件f2.obj引用了符号fillclr; ④ 库libc.libc的成员Member0包含orign的定义; ⑤ 库libc.liba的成员Member3包含fillclr的定义; ⑥ 两个库成员Member3包含fillclr定义;2021/8/6101 若输入命令: lnk500 f1.obj liba.lib f2.obj libc.lib 则引用分辨如下: ① 库libc.liba的成员Member1满足对clrscr引用,因为f2.obj引用它之前,库被搜索并定义了clrscr。

      ② 库libc.libc的成员Member0满足对origin的引用 ③ 库libc.liba的成员Member3满足对fillclr的引用2021/8/6102 但如果输入命令: lnk500 f1.obj f2.obj libc.lib liba.lib 则所有对clrscr的引用都由库libc.libc的成员Member1满足2021/8/6103 4.5.4 MEMORY命令 链接器应当确定输出各段放在存储器的什么位置要达到这个目的,首先应当有一个目标存储器的模型 MEMORY命令就是用来规定目标存储器的模型通过这条命令,可以定义系统中所包含的各种形式的存储器,以及它们占据的地址范围2021/8/6104 例4.5.2 使用MEMORY伪指令的链接器命令文件的例子 file1.obj file2.obj -o Prog.out MEMORY { PAGE 0: ROM:origin=C00h, length=1000h PAGE 1: SCRATCH: origin=60h, length=20h ONCHIP: origin=80h, length=200h }2021/8/6105 例4.5.2中MEMORY命令所定义的系统,其存储器配置如下: 程序存储器:4K ROM,起始地址C00h,取名为ROM。

      数据存储器:32字 RAM,起始地址60h,取名为SCRATCH 512字 RAM,起始地址80h,取名为ONCHIP.2021/8/6106 MEMORY命令一般句法如下: MEMORY { PAGE 0: name 1[(attr)]: origin=constant, length=constant; PAGE n: name n[(attr)]: oringin=constant, length=constant; }2021/8/6107 PAGE—代表一个完全独立的存储空间,页号n最多为255通常PAGE 0定为程序存储器, PAGE 1定为数据存储器如果没规定,默认为PAGE 0name—对存储区间取名attr—这是任选项,为命名区规定1~4个属性: R—可对存储器执行读操作; W—可对存储器执行写操作; X—存储器可以装入可执行的程序代码; I—可对存储器进行初始化如果一项属性都没选,则存储器具有全部4项属性Origin—规定存储区的起始地址。

      Length—指定存储空间的长度2021/8/6108 4.5.5 SECTIONS命令 SECTIONS命令的任务如下: ◆ 说明如何将输入段组合成输出段 ◆ 在可执行程序中定义输出段 ◆ 规定输出段在存储器中的存放位置 ◆ 允许重新命名输出段2021/8/6109 SECTIONS命令一般句法如下: SECTIONS { name:[property, property, property,…] name:[property, property, property, …] name:[property, property, property, …] } 在连接命令文件中, SECTIONS命令用大写字母,紧随其后并用大括号括起来的是关于输出段的详细说明每一个输出段的说明都从段名开始,段名后面是一行说明段的内容和如何给段分配存储单元的性能参数一个段可能的性能参数有:2021/8/6110 ◆Load allocation,由它定义将输出段加载到存储器中的什么位置 句法:load=allocation 或 >allocation 或 allocation具体写法有多种形式,例如.text: load=0x1000.text: load > ROM.text: PAGE0.bss: load >(RW) 2021/8/6111 ◆ run allocation,由它定义输出段在存储器的什么位置上开始运行。

      句法: run =allocation 或 run > allocation 链接器为每个输出段在目标存储器中分配两个地址:一个是加载的地址,另一个是执行程序的地址 通常,这两个地址是相同的,可以认为每个输出段只有一个地址2021/8/6112 有时要把程序的加载区分开,只要用SECTIONS命令让链接器对这个段定位两次就行了一次是设置加载地址,另一次是设置运行地址 例如: .fir:load=ROM,run=RAM◆Input_sections,用它定义有哪些输入段组成输出段 句法: {Input_sections}2021/8/6113 多数情况下,在SECTIONS命令中不列出每个输入文件的输入段的段名,即 SECTIONS { .text: .data: .bss } 这样,在链接时,链接器就将所有输入文件的.text段链接成.text输出段(其他段也一样)2021/8/6114 当然,也可以明确地用文件名和段名来规定输入段,即 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段*/ } }2021/8/6115 4.5.6 多个文件的链接实例.title“example.asm”.mmregsstack.usect“STACK”, 10h.bssa,4.bssx,4.bssy,1.defstart.datatable:.word1,2,3.4.word8,6,4,2.textstart:STM#0,SWWSRSTM#STACK+10h,SPRPT#7MVPDtable,*AR1+CALLSUMend:BendSUM:STM#a, AR3STM#x, AR4RPTZA, #3MAC*AR3+,*AR4+,ASTLA, @yRET.end2021/8/6116 下面以example.asm源程序为例,将复位向量列为一个单独的文件,对两个目标文件进行链接。

      ① 编写复位向量文件vectors.asm .title “vectors.asm” .ref start .sect “vectors” B start .end2021/8/6117 ② 编写源程序; ③ 分别对两个源文件example.asm和vector.asm进行汇编; ④ 编写链接命令文件example.cmd此命令文件链接examples.obj和vectors.obj两个目标文件,并生成一个映像文件example.map以及一个可执行的输出文件example.out2021/8/6118 例 链接器命令文件example.cmd vectors.objexample.obj-o example.out-m example.map-e startMEMORY{ PAGE0: EPROM:org=0E00h,len=100hVECS:org=0FF80h,len=04h PAGE1:SPRAM:org=0060h,len=20hDARAM:org=0080h,len=100h}SECTIONS{ .text :>EPROM PAGE0 .data :>EPROM PAGE0 .bss :>SPRAM PAGE1 STACK :>DARAM PAGE1 .vectors :>VECS PAGE0 2021/8/6119 ⑤ 链接。

      链接后生成一个可执行的输出文件example.out和映像文件example.map 例 映像文件example.map OUT FILE NAME: ENTRY POINT SYMBOL: “start” address: 0000e000MEMORY CONFIGURATION name origin length attributes fill PAGE0: EPROM 0000e000 000000100 RWIX VECS 0000FF80 000000004 RWIXPAGE1: SPRAM 00000060 000000020 RWIX DARAM 00000080 000000100 RWIXSECTION ALLOCATION MAPoutputsection page origin length attributes/input sections2021/8/6120 .text 0 0000e000 00000016 0000e000 00000000vectors.obj(.text) 0000e000 00000016example.obj(.text).data 0 0000e016 00000008 0000e016 00000000vectors.obj(.data) 000e016 00000008example.obj(.data).bss 1 00000060 00000009UNINTIALIZED 00000060 00000000vectors.obj(.bss) 00000060 00000009example.obj(.bss)STACK 1 00000080 00000010UNINITIALIZED 00000080 00000010example.obj(STACK).vectors 0 0000ff80 00000002 0000ff80 00000002vectors.obj(.vectors).xref 0 00000000 0000008cCOPY SECTION 00000000 00000016vectors.obj(.xref) 00000016 00000076example.obj(.xref)2021/8/6121 GLOBAL SYMBOLSaddress name address name00000060 .bss 00000060 .bss0000e016 .data 00000069 end0000e000 .text 0000e000 .start0000e01e edata 0000e000 .text00000069 end 0000e016 etext0000e016 etext 0000e016 .data0000e000 start 0000e01e .edata[7 symbols]2021/8/6122 部分资料从网络收集整理而来,供大家参考,感谢您的关注! 。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.