以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
参考博客
链接脚本基本语法_Nerazzur的博客-CSDN博客_链接脚本语法(推荐)
链接脚本语法_ABCamus的博客-CSDN博客_链接脚本语法
链接地址、运行地址、加载地址、存储地址_嵌入式Sky的博客-CSDN博客_链接地址
链接脚本(link script)语法 - aspirs - 博客园
Linker scripts (推荐)
一、链接脚本的含义及作用
链接脚本是一个规则文件,用来指导链接器工作。链接器会根据链接脚本中的规则,去处理.o文件中的程序段(一般情况下每个.o文件会包含若干个程序段,而不是只有某个程序段),将其链接成一个可执行程序。
二、链接脚本的组成及语法
1、基本语法
简单的链接脚本内容如下,可见其关键内容有两部分,即链接地址、程序段。
SECTIONS //SECTIONS{},这个表示整个链接脚本。 { //这句代码表示链接地址是0xd0024000. = 0xd0024000; //点号,在链接脚本中代表当前位置。//等号,在链接脚本中表示赋值操作。.text : {// 段名为.text,即文本段start.o* (.text)}.data : {* (.data)}bss_start = .; .bss : {* (.bss)}bss_end = .; }
2、链接地址
在程序编译的时候,每个目标文件都是由源代码编译得到,最终多个目标文件链接生成一个可执行文件,而链接地址就是告知链接器,各个目标文件在可执行程序中的位置。比如,一个可执行程序a.out由a.o、b.o、c.o组成,那么最终的a.out中谁在前谁在中间谁在结尾,都可以通过制定链接地址来决定。链接地址是静态的,在进行程序编译的时候指定的。
P.S.上面这段话感觉是链接脚本的含义,而不是链接地址的含义。我理解的链接地址,指的是可执行文件将来要下载到哪个地址;链接地址在链接脚本中只定义一次,即链接脚本开头的第一句代码“ . = 0xd0024000; ”。但实际学习下来,好像上面这段话是对的。
3、程序段程序段,是指程序的某部分。整个程序可以分为许多程序段,我们给这些程序段起名字,方便在链接的时候用段名来指代这些段,从而让这些程序段位于合适的位置。
程序段分为以下几种:代码段(.text)、数据段(.data)、bss段(ZI段)、自定义段。其中代码段(.text)、数据段(.data)、bss段(ZI段)这些段名是编译器链接器内部定好的。程序员也可以自己给某些段起名字,这些段就称为自定义段。
(1)代码段:也叫文本段,用符号“.text”表示。它其实就是函数编译后生成的东西。
(2)数据段:用符号“.data”表示,它其实就是C语言中有显式初始化为非0的全局变量。
(3)bss 段:也叫ZI段,即零初始化段,用符号“.bss”表示。它对应C语言中初始化为0(或者没有显式初始化)的全局变量。
(4)自定义段:段名由程序员自己定义,段的属性和特征也由程序员自己定义。
4、拓展说明
(1)C语言中全局变量如果未显式初始化则其值为何是0?
本质就是C语言把这类全局变量放在了bss段,从而保证其值为0。
(2)如何保证显式初始化为非0的全局变量的值在main之前就被赋值了?
编译器与链接器这类变量放在.data段中,而.data段会在main执行之前被处理(初始化)。