打印

TMS320C55x汇编语言知识

[复制链接]
834|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qwe890asd|  楼主 | 2017-10-23 10:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
TMS320C55x汇编语言知识


   1.通用目标文件格式 ---- COFF,common object file format段(section)是COFF文件的基本单元。
一个段是一个占据存储器里连续地址的代码或者数据块,COFF目标文件的每个段都是分开和不同的
    COFF目标文件通常包括3个默认段
    .text段,通常包含可执行代码
    .data段,通常包含初始化数据
    .bss段, 通常为未初始化变量保留存储空间
    一些汇编伪指令可将代码和数据的各个部分与相应的段相联系,可以更有效地利用存储器,用户可以将任何段放到存储器的任何存储块上
   
    2. 汇编器对段的处理
    汇编器通过段伪指令自动识别各个段,并将段名相同的语句汇编在一起
    汇编器有5条伪指令可以识别汇编语言程序的各个不同段
    .text、.data、.sect创建初始化段
    .bss和.usect创建未初始化段
    .sect与.usect创建自定义段和子段

    2.1 未初始化段
    未初始化段占用处理器存储空间,常常分配到RAM
    未初始化段在目标文件里没有实际内容,仅仅用于保留存储空间,当程序在运行时用这些空间来创建和存储变量
汇编命令.bss和.usect用来创建未初始化数据区域
    .bss symbol, size [,[blocking flag][,alignment flag]]
    symbol .usect “section name”, size [,[blocking flag][,alignment flag]]
    symbol:指向.bss指令创建的段的第一个字,对应该存储空间的变量名。可被其他段引用,被声明为一个全局符号
    size:为对应段开辟的存储空间大小,单位为字
    blocking flag:可选参数。如果赋予一个非零值给该参数,汇编器会连续分配字节空间,这些区域不会超出一页边界,除非该段大于一页。
    alignment flag: 可选参数。如果赋予一个非零值给该参数,该段会在一个长字边界开始
    section name:段名
   
    2.2 .初始化段
    初始化段包含可执行代码或者初始化数据;当程序被装载时,它们就被放到处理器存储空间里
    每个初始化段独立分配空间,可以引用在其他段定义的标识(symbol),链接器自动处理这些段间引用
    定义初始化段的指令:
    .text
    .data
    .sect ”section name”[,value] value表示段指针SPC的初值,默认为0
   
     2.3 自定义段
    usect 创建像.bss段那样的段,这些段为变量在RAM开辟存储空间。
    .sect创建像.text和.data段那样包含代码和数据的段,可以创建可重分配地址的自定义段。
    用户可以创建多达32767个自定义段,段名多至200个字符。
    每次使用这两个指令可以用不同的section name来创建不同的段,如果用一个已经使用的section name,那么汇编器将代码和数据都汇编到同一个段。

    2.4 子段
    子段是更大的段中的较小的段,链接器可以像段一样操作它
    子段让用户可以更好的控制存储器映射
    可以使用.sect或者.usect指令来创建子段,格式为:
    section name:subsection name

   例,在段.text中创建一个_func子段如下:
    .sect “text:_func”

   用户可以为其单独分配地址,也可以和.text段的其他部分一起分配地址
   
    2.5 段指针SPCs
    汇编器为每个段安排一个独立的程序计数器,即段程序计数器(SPC)。SPC表示一个程序代码段或数据段内的当前地址。开始时,汇编器将每个SPC置0,当汇编器将程序代码或数据加到一个段内时,相应的SPC增加。如果汇编器再次遇到相同段名的段,继续汇编至相应的段,且相应的SPC在先前的基础上继续增加。

    3 链接器对段的处理
    链接器对段的处理:将一个或多个COFF目标文件(.obj)中的各种段作为链接器的输入段,经链接后在一个可执行的COFF模块(.out)中建立各个输出段
    为各个输出段选定存储器地址
    链接器有2条伪指令支持上述任务:
    ● MEMORY伪指令——用来定义目标系统的存储器配置空间,包括对存储器各部分命名,以及规定它们的起始地址和长度。
    ● SECTIONS伪指令——用来指定链接器将输入段组合成输出段方式,以及输出段在存储器中的位置,也可用于指定子段。
若未使用伪指令,则链接器将使用目标处理器默认的方法将段放入存储空间。
    如果在链接时不使用MEMORY和SECTIONS指令,则链接器使用目的处理器的默认分配算法;
    有时用户不想使用默认设置,要自己进行存储器映射,就要使用MEMORY和SECTIONS等链接指令。

    4 链接器对程序的重新定位
    汇编器对每个段汇编时都是从0地址开始,而所有需要重新定位的符号(标号)在段内都是相对于0地址的。事实上,所有段都不可能从存储器中0地址单元开始,因此链接器必须对各个段进行重新定位。

    1.地址重定位
    重新定位的方法:
     将各个段配置到存储器中,使每个段都有一个合适的起始地址;
     将符号变量调整到相对于新的段地址的位置;
     将引用调整到重新定位后的符号,这些符号
    反映了调整后的新符号值。
    汇编器在需要引用重新定位的符号处都留了一个重定位入口。链接器在对符号重新定位时,利用这些入口修正对符号的引用值。
    2.运行时间重定位
    在实际运行中,有时需要将代码装入存储器的一个地方,而在另一个地方运行。
    如:一些关键的执行代码必须装在系统的ROM中,但运行时希望在较快的RAM中进行。
    利用SECTIONS伪指令选项可让链接器对其定位2次,其方法:
    ① 使用装入关键字设置装入地址;
    ② 使用运行关键字设置它的运行地址。
    装入地址确定段的原始数据或代码装入的位置,而任何对段的使用(例如其中的标号),则参考它的运行地址。在应用中必须将该段从装入地址复制到运行地址。
    如果只为段提供了一次定位(装入或运行),则该段将只定位一次,并且装入和运行地址相同。如果提供了2个地址,则段将被自动定位。

    5 COFF文件中的符号
    COFF文件中有一张存放程序中的外部符号信息的符号表.该表在连接器重定位和程序调试时都要用到。
    外部符号:
    在一个模块中定义而在另一个模块中引用的符号,由.def、.ref和.global伪指令来定义。
    .def (定义):在当前模块中定义而在别的模块中引用的符号
    .ref(引用):在当前模块中引用而在别的模块中定义的符号
    .global(全局):在当前模块中定义而在别的模块中引用的符
   符号表:
    每当遇到一个外部符号,无论是定义的还是引用的,汇编器都将在符号表中产生一个条目。
    汇编器还产生一个指到每段的专门符号,链接器使用这些符号将其他引用符号重新定位。

    6 C55x汇编器的特点
    1.代码字节寻址,数据字寻址。
    2.可变长度指令解码
    3.存储器模式选择:C54x兼容模式,CPL模式,ARMS模式。
    4.MMR寻址警告。

    7.汇编伪指令
    汇编伪指令为程序提供数据和汇编过程的控制,功能有:
    把代码和数据汇编到指定的段
    在存储区为非初始化变量保留存储空间
    控制列表文件的内容
    初始化存储器
    声明全局变量
    指定程序要调用宏指令的宏指令库
    检查符号调试信息
    汇编伪指令和它的参数必须书写在一行中,可以带有标号和注释

    8.宏指令
    如果程序中需要多次执行某段程序,可以把这段程序定义(宏定义)为一个宏,然后在需要重复执行这段程序的地方调用这条宏。
    如果需要多次引用一个宏,但是每次都有不同的数据,可以在宏里使用参数,每次使用时赋予参数不同值即可
    宏指令的作用主要是:
    定义自己的宏指令和重新定义已存在的宏指令
    简化长的或者复杂的汇编代码
    访问指令库
    在一个宏里定义有条件和可重复块
    在一个宏里操作字符串
    控制扩展列表

    可以在程序的任何位置定义宏
    必须在使用前定义
    可以在源文件的开始,在.include/.copy文件或者在一个宏指令库里定义一个宏
    宏定义可以嵌套。可以在定义里引用其他的宏,但是这些宏都必须和当前定义的宏在同一个文件里

    宏定义的格式:
    macname .macro [parameter 1][,…,parameter n]
    ……..宏程序语句或宏伪指令
    [.mexit]
    .endm
    macname: 宏程序名称,必须将名称放在源程序标号域。
    .macro: 用来说明该语句为宏定义的第一行伪指令,
    必须放在助记符操作码区域。
    parameters: 为任选的替代参数,作为宏指令的操作数。
    宏程序语句: 每次宏调用时要执行的指令或汇编命令。
    宏伪指令: 用于控制宏指令展开的命令。
    .mexit: 相当于一条跳到.endm语句。
    .endm: 结束宏定义。

9.其他伪指令
    .mmregs — 定义存储器映射寄存器的名称,这样就可以用AR0、PMST等助记符替换实际的存储器地址。
    ...........
   
    10.C55x汇编语言源文件的书写格式
    一条语句占源程序的一行
    总长度可以是源文件编辑器格式允许的长度
    语句的执行部分必须限制在200个字符以内
    所有包含有汇编伪指令的语句必须在一行完成指定
    如果源程序很长,需要书写若干行,可以在前一行用反斜杠字符(\)结束,余下部分接着在下一行继续书写
    标号是由字母、数字以及下划线和$等组成,最多可32个字符
    标号分大小写,且第一个字符不能是数字
    助记符用来表示指令所完成的操作,可以是汇编语言指令、汇编伪指令、宏指令。其中:
    助记符指令:一般用大写,不能从第一列开始
    汇编伪指令:用来为程序提供数据和控制汇编进程,
    以句号“.”开始,且用小写
    宏指令:用来定义一段程序,以便宏调用来调用这段程序,
    以句号“.”开始,且用小写
    宏调用:用来调用由宏伪指令定义的程序段
    作为操作数的前缀有三种情况:
    使用“#”号作为前缀,汇编器将操作数作为立即数处理
    使用“*”符号作为前缀,汇编器将操作数作为间接地址,即把操作数的内容作为地址
    使用“@” 符号作为操作数的前缀。汇编器将操作数作为直接地址,即操作数由直接地址码赋值

    浮点数 1.623e-23 仅用于C语言
    汇编程序中的符号用于标号、常数和替代字符。由字母、数字及下划线和美元符号(A~Z,a~z,0~9,_和$)等组成。
    符号名最多可长达200个字符。
    在符号中,第1位不能是数字,并且符号中不能含空格。
    内建数学函数中的表达式必须为常数

    11 TMS320C55x链接器
    TMS320C55x链接器有两个功能强大的指令,即MEMORY和SECTIONS。
    MEMORY指令允许用户定义一个目标系统的存储器映射,可以命名存储器的各个部分,并且指定开始地址和大小。
    SECTIONS指令告诉链接器合成输入段为输出段,并且告诉链接器把这些输出段放在存储器的某个位置。

    MEMORY: 用来指定目标存储器结构
    SECTIONS:用来控制段的构成与地址分配
    1 、MEMORY指令
MEMORY
{
[PAGE 0:] name_1[(attr)]:o=constant,l=constant;

[PAGE n:] name_n[(attr)]:o=constant,l=constant;
}


  其中:
   PAGE:
    用于识别一个存储空间,可以使用多达255个页
    通常页0对应程序存储空间,页1对应存储器空间
    每个页面表现为一个完全独立的地址空间

    Name:
    命名一个存储空间
    可以是任意合法字符
    存储空间名字仅对链接器有用,在输出文件或者符号里不再保留
    在不同页的存储空间范围可以有相同的名字,但在一页内不允许不同空间段有相同名字和交叠。

   attr:
    指定与命名的存储空间范围相联系的
    1~4个属性,使用时必须放在小括号里

    合法的属性包括:
    R:表示该存储空间可读
    W:表示该存储空间可写
    X:表示该存储空间可以包含可执行代码
    I:表示该存储空间可以初始化
    o:指定存储段的开始地址。值为24位常数,可以是十进制、八进制或十六进制,单位为字节,也可写为org
    l:指定存储段的长度。值为24位常数,可以是十进制、八进制或者十六进制,单位为字节,也可以写len
SECTIONS
{
oname_1:[property, property, property …]
oname_2:[property, property, property …]
oname_3:[property, property, property …]
}


  其中:以oname开始的一行定义了一个输出段。段名oname后是属性列表,这些属性定义了段的内容和段如何分配到存储器。一个段可能的属性包括:
    Load allocation 定义在存储器中段被装载的位置: load=allocation 或 allocation 或 >allocation
    Run allocation 定义在存储器中段运行的位置:
    run=allocation 或run > allocation
    Input sections 定义组成输出段的输入段:
    句法为 {input_sections}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

455

主题

583

帖子

5

粉丝