《连接脚本相关》word版_第1页
《连接脚本相关》word版_第2页
《连接脚本相关》word版_第3页
《连接脚本相关》word版_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、连接脚本相关知识一个程序本质上都是由 bss段、data段、text段三个组成的。这样的概念,不知道最初来源于哪里的规定,但在当前的计算机程序设计中是很重要的一个基本概念。而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。用于存放没有被初始化的或者初始化为0的全局变量和静态变量。数据段:数据段(data segment)通常是指用来存放程序中已初始化的全

2、局变量的一块内存区域。数据段属于静态内存分配。用于存放已经初始化过的(且初始化值不为0)的全局变量和静态变量。代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内

3、存时,被释放的内存从堆中被剔除(堆被缩减)栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。SECTIONS /该链接脚本,就是用来对bss段、data段、text段进行有效的排版的!. = 0x00000000;.text : *(.

4、text) /冒号:两边一定要有空格!. = 0x32000000;.data : *(.data)_bss_start = .;.bss : *(.bss) _end = .;注意:1.若为nor flash启动,为什么. = 0x32000000不能够改成. = 0x1000呢?那是因为nor flash的只读不写的特 性决定了的,当程序再次初始化bss中的全局变量的时候,是不可能完成的! 2.一般bss段是紧跟在data段后面的!问:怎么理解一个连接地址?答:以一个没有被初始化的变量i为例子(在编译的时候,它会被归为BSS段的):a. 当连接地址指定为0x00000000时,那么编译的时

5、候,编译器给i分配的地址可能是0x00000000后一小段的的某个地址(查看反汇编可以得知);b. 当连接地址指定为0x30000000时,那么编译的时候,编译器给i分配的地址可能是0x30000000后一小段的的某个地址(查看反汇编可以得知);c. 所以,可以感悟出,如果我们的连接地址是0x300000000,而我们在没有重定位之前,想去访问这个i变量,那绝对会失败的。总结:1. 程序运行时,“应该”位于它的连接地址;2. 但是由于硬件的特性决定,程序最开始执行时,是从0x0地址开始的,所以,再最开始的几段代码里面,需要实现重定位,这几段代码实现把程序拷贝到连接地址去,然后执行,如果不拷贝到

6、连接地址去,那么将得不到理想的上述的i变量;3. 既然程序应该从连接地址开始运行,那么为什么,上述的最前面的代码却可以运行呢?因为最前面的代码都是使用的是位置无关码。位置无关码-相对寻址和绝对寻址相对寻址:用到的指令: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只能跳转+-32

7、MB,所以他不能够完成大的跳转(从0x04跳转到0x30000000)!所以一般使用相对寻址指令时,使用的地址,任然是ram中的地址;绝对寻址:用到的指令:ldr pc, =main它的反汇编:ldr pc, pc, #num解释:pc等于(当前pc的地址加上一个偏移num地址后得到的相对地址)中取取到的地址数据。这个数据会是由(-Ttext 连接地址)指定的连接地址后边的地址!这时候便实现了大跳转(如从0x04跳转到0x30000000)!因此在内存没有初始化好,或者还没有重定位之前,就执行这样的绝对寻址,那么将得不到想要的数据,那么程序就会因此而死掉!问:什么是位置无关码?答:问:位置无关

8、码,到底是用来实现相对寻址,还是绝对寻址的呢?答:位置无关码,是用来实现相对寻址的!问:怎么使用位置无关码?答:a. 使用相对寻址的指令;b. C语言中不使用全局变量,静态变量问:为什么不能够使用全局变量,静态变量?答:不能使用全局变量的原因是这样的:我们的裸编程序在链接(arm-linux-ld)的时候,会进行重定位,建立符号规则,为变量,函数分配运行地址,也就是我们在链接脚本里定义的0x30000000这个地址。但问题就来了,如果我们在初始化这个阶段(也就是还没重定位到sdram之前)使用了全局变量,那么这个全局变量的运行地址会被映射到SRAM中,这个不好的地方就是,即便以后ldr pc,

9、=main之后跳到0x30000000地址上去了,但在这个地址上如果要访问这个全局变量,这个变量就要在映射表中查询,发现这个变量还在SRAM中,那么程序就会跳回到SRAM中,这个不是我们希望的。所谓的映射是:在编译的时候,会有个映射表,里边存的是变量,函数的地址。这样当程序运行的时候,cpu方 便在表中查询相应的变量,函数地址。注意:局部变量是在栈里的,而不是在这个映射表里面,所以初始化的程序里有ldr sp, =4096,是为了设置sram 的栈空间,用于保存局部变量等。结论:所以我们不要在重定位之前在映射表中留有变量的痕迹,也就是说不要使用全局变量例如:(注意对比!)例1:lowlevel

10、_init:/* memory control configuration */* make r0 relative the current location so that it */* reads SMRDATA out of FLASH rather than memory ! */ldr r0, =SMRDATA /注意:用的是绝对寻址!ldrr1, _TEXT_BASEsubr0, r0, r1 /因为用的是绝对寻址,所以这里要做这样的操作!ldrr1, =BWSCON/* Bus Width Status Controller */add r2, r0, #13*40:ldr r3

11、, r0, #4str r3, r1, #4cmp r2, r0bne 0b/* everything is fine now */movpc, lr.ltorg/* the literal pools origin */SMRDATA: .word (0+(B1_BWSCON4)+(B2_BWSCON8)+(B3_BWSCON12)+(B4_BWSCON16)+(B5_BWSCON20)+(B6_BWSCON24)+(B7_BWSCON28) .word (B0_Tacs13)+(B0_Tcos11)+(B0_Tacc8)+(B0_Tcoh6)+(B0_Tah4)+(B0_Tacp2)+(B

12、0_PMC) .word (B1_Tacs13)+(B1_Tcos11)+(B1_Tacc8)+(B1_Tcoh6)+(B1_Tah4)+(B1_Tacp2)+(B1_PMC) .word (B2_Tacs13)+(B2_Tcos11)+(B2_Tacc8)+(B2_Tcoh6)+(B2_Tah4)+(B2_Tacp2)+(B2_PMC) .word (B3_Tacs13)+(B3_Tcos11)+(B3_Tacc8)+(B3_Tcoh6)+(B3_Tah4)+(B3_Tacp2)+(B3_PMC) .word (B4_Tacs13)+(B4_Tcos11)+(B4_Tacc8)+(B4_Tc

13、oh6)+(B4_Tah4)+(B4_Tacp2)+(B4_PMC) .word (B5_Tacs13)+(B5_Tcos11)+(B5_Tacc8)+(B5_Tcoh6)+(B5_Tah4)+(B5_Tacp2)+(B5_PMC) .word (B6_MT15)+(B6_Trcd2)+(B6_SCAN) .word (B7_MT15)+(B7_Trcd2)+(B7_SCAN) .word (REFEN23)+(TREFMD22)+(Trp20)+(Trc18)+(Tchr16)+REFCNT) .word 0xb1 .word 0x30.word 0x30例2:memsetup: 设置存储控

14、制器以便使用SDRAM等外设 mov r1, #MEM_CTL_BASE 存储控制器的13个寄存器的开始地址 adrl r2, mem_cfg_val 这13个值的起始存储地址 (注意:用的是相对寻址!) add r3, r1, #52 13*4 = 541: ldr r4, r2, #4 读取设置值,并让r2加4 str r4, r1, #4 将此值写入寄存器,并让r1加4 cmp r1, r3 判断是否设置完所有13个寄存器 bne 1b 若没有写成,继续 mov pc, lr 返回.align 4mem_cfg_val: 存储控制器13个寄存器的设置值 .long 0x22011110 BWSCON .long 0x00000700 BANKCON0 .long 0x00000700 BANKCON1 .long 0x00000700 BANKCON2 .lo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论