连接足本相干.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
连接足本相干

连接脚本相关知识 一个程序本质上都是由 bss段、data段、text段三个组成的。这样的概念,不知道最初来源于哪里的规定,但在当前的计算机程序设计中是很重要的一个基本概念。而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。 BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。用于存放没有被初始化的或者初始化为0的全局变量和静态变量。 数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。用于存放已经初始化过的(且初始化值不为0)的全局变量和静态变量。 代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。 堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减) 栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。 SECTIONS //该链接脚本,就是用来对bss段、data段、text段进行有效的排版的!! { . = 0 .text : {*(.text)} //冒号:两边一定要有空格!!!!!!! . = 0 .data : {*(.data)} __bss_start = .; .bss : { *(.bss) } _end = .; } 注意:1.若为nor flash启动,为什么. = 0能够改成. = 0x1000呢?那是因为nor flash的只读不写的特 性决定了的,当程序再次初始化bss中的全局变量的时候,是不可能完成的!!!!! 2.一般bss段是紧跟在data段后面的!!!! 问:怎么理解一个连接地址? 答:以一个没有被初始化的变量i为例子(在编译的时候,它会被归为BSS段的): 当连接地址指定为0,那么编译的时候,编译器给i分配的地址可能是0一小段的的某个地址(查看反汇编可以得知); 当连接地址指定为0,那么编译的时候,编译器给i分配的地址可能是0一小段的的某个地址(查看反汇编可以得知); 所以,可以感悟出,如果我们的连接地址是0x300000000,而我们在没有重定位之前,想去访问这个i变量,那绝对会失败的。 总结: 程序运行时,“应该”位于它的连接地址; 但是由于硬件的特性决定,程序最开始执行时,是从0x0地址开始的,所以,再最开始的几段代码里面,需要实现重定位,这几段代码实现把程序拷贝到连接地址去,然后执行,如果不拷贝到连接地址去,那么将得不到理想的上述的i变量; 既然程序应该从连接地址开始运行,那么为什么,上述的最前面的代码却可以运行呢?因为最前面的代码都是使用的是位置无关码。 位置无关码 --相对寻址和绝对寻址 相对寻址: 用到的指令:bl,b,adr指令 bl,b的反汇编:add r0, pc, #num 解释:pc等于相对与当前pc+一个num数的偏移地址,相对与当前pc的一个跳转,这就是相对跳转。 adr的反汇编:sub,r0,pc,#num 解释:r0等于相对与当前pc减去一个num数的偏移地址,就得到程序真正从哪里开始执行的地址了,那个num的值,是由编译器决定的。 注意:因为bl, b,adr只能跳转+-32MB,所以他不能够完成大的跳转(从0x04跳转到0!!所以一般使用相对寻址指令时,使用的地址,任然是ram中的地址; 绝对寻址: 用到的指令:ldr pc, =main 它的反汇编:ldr pc, [pc, #num] 解释:pc等于(

文档评论(0)

f8r9t5c + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:8000054077000003

1亿VIP精品文档

相关文档