杭州网站关键词排名优化,wordpress特效ios没反应,营销型网站建设的价格,简述app开发流程文章目录 静态链接空间与地址分配相似段合并虚拟地址分配符号地址确定 符号解析与重定位链接器优化重复代码消除函数链接级别 静态库静态链接优缺点 静态链接
一组目标文件经过链接器链接后形成的文件即可执行文件#xff0c;如果没有动态库的加入#xff0c;那么这个可执行… 文章目录 静态链接空间与地址分配相似段合并虚拟地址分配符号地址确定 符号解析与重定位链接器优化重复代码消除函数链接级别 静态库静态链接优缺点 静态链接
一组目标文件经过链接器链接后形成的文件即可执行文件如果没有动态库的加入那么这个可执行文件被加载后无需再进行重定位操作(符号已经在链接阶段全部得到重定位)这种方式即静态链接静态链接的过程分为空间与地址分配符号解析与重定位
空间与地址分配
空间与地址分配阶段链接器需要为各个节分配虚拟地址分配虚拟地址的第一步就是要把各个目标文件的节进行合并现代链接器都是采用相似段合并的方式对目标文件的节进行合并所谓相似节合并即多个目标文件的代码节合一起数据节合一起…
相似段合并
链接器扫描所有目标文件各个节的信息获取其长度对相似节进行合并合并完后的节在代码段中称为段。实际上ELF文件中既能称作节(section),也能称作段(segment),但是可执行文件中一般都是称为段并且有个更专业的术语称为执行视图而目标文件中的节称为链接视图 虚拟地址分配
//a.c
extern int shared;
int main(){int a0;swap(a,shared);return 0;
}
//b.c
int shared1;
void swap(int* a,int* b){*a^*b*a^*b;
}观察2个源文件的目标文件节信息
只需要关注红框选中的三个字段size和file off为节的大小和在目标文件中偏移量而VMA是虚拟地址很明显0地址是无效的它们其实都还没有被分配虚拟地址这很正常因为它们只是目标文件是不能被执行的也就没有必要分配什么虚拟地址了但是由它们静态链接所产生的可执行文件具有有效的虚拟地址 合并后段大小不严格等于目标文件中对应的节大小之和是因为链接过程中还会添加一些额外信息
符号地址确定
目标文件中的各个符号都有相对于节起始位置的偏移量这个偏移量很重要符号地址的确定依赖它对于一个符号来说它在目标文件中的地址和在可执行文件中的地址是不一样的链接后这些符号的绝对地址一定会发生变化为了后续符号解析与重定位可以正常进行就需要确定符号在可执行文件中的地址如何确定就是通过这个不变的偏移量(符号地址再怎么变化它相对于所在节的偏移量是始终不会发生改变的链接器不会把一个节拆开) 符号解析与重定位
这一步是静态链接的核心步骤基本上所有的链接错误都是发生在这个阶段因为该阶段链接器的工作是确定外部符号引用的绝对地址如果存在需要重定位但是找不到其定义的符号就直接报错。
重定位工作之前链接器必须知道可执行文件有哪些符号哪些符号是需要被重定位的因此链接器需要借助可执行文件中的全局符号表和全局重定位表这2张表由是多个目标文件的符号表和重定位表合并而来的因此可执行文件中的符号表和重定位表由第一步空间与地址分配完成 对于没有经过重定位的目标文件来说那些外部符号的符号值是没有意义的 链接器将所有的外部符号进行重定位后 经过重定位后CPU就可以通过这个有效的操作数进行相对寻址正确的访问数据和执行函数
链接器优化
重复代码消除
//template.h
templatetypename TT add(T x,T y){return xy;
}
//a.cc
int main(){add(1,2);return 0;
}
//b.cc
int ADD(int x,int y){return add(x,y);
}C中引入了模板一个模板函数可能被多个源文件所实例化这会造成重复的代码例如a.cc和b.cc实例化出的函数都是int add(int,int),链接器会对其进行合并减少不必要的空间浪费(可执行文件中的代码段只有一份int add(int,int))
更加专业的解释
编译器在每个翻译单元中生成模板函数的实例链接器在链接这些对象文件时会注意到多个相同的函数实例例如 int add(int, int)但不会报错因为它会自动选择其中一个实例忽略其他重复的实例(前提是定义在头文件中,这样编译器才能实例化)这种行为是由C标准规定的称为“外部链接”的模板实例化
模板请不要声明和定义分离这会造成链接错误
函数链接级别
目标文件中所定义的函数不一定在可执行文件中都会被使用如果无脑地将所有函数全都放入可执行文件的代码段这会造成无端的空间浪费链接器引入了人函数链接级别的概念来优化简单来说就是只把可执行文件中用到的函数写入可执行文件的代码段不会用到的那些函数定义丢弃
静态库
静态库即一组目标文件的集合Linux下通过ar命令对一组目标文件进行打包
ar -rc libmine.a a.o b.o通过静态库链接可以简化命令行链接器会在链接过程中从静态库中寻找所需要的数据或函数定义
gcc/g在链接时默认采用动态链接显示的静态链接需要添加-static选项
静态链接优缺点
优点
过程较为简单一旦成功生成可执行文件后就可以直接运行并且不会有库依赖问题
缺点
可执行文件很大因为静态链接的可执行文件将所有目标文件都进行合并多个可执行文件可能静态链接了相同的库但是它们运行时无法共享代码段(即使代码段是一样的)这会造成内存中存在多份一样的代码升级维护困难静态库的任何更新操作需要重新编译链接生成新的可执行文件
————————————————————————————————————