为什么我们有不同架构的连接器?链接器的服务是解析地址。那么它如何与目标架构的指令相关?
答案 0 :(得分:9)
有许多原因,我无法详尽地列出所有原因。
当架构不支持与位置无关的代码时,链接器需要做更多的工作。在这些情况下,甚至在函数中跳转都需要解决。
链接器需要创建特定于体系结构的标头,例如ELF或PE标头。
链接器需要在支持它们的平台上包含资源,数据叉或类似的东西
链接器需要实例化导出的C ++模板
链接器还需要处理尚无法解决的地址。这可以包括系统调用或动态加载的库。
链接动态库时,链接器需要导出多个输入函数。不同的体系结构使用不同的方法来指示要导出的函数
如果在编译时无法确定,则链接器可能需要插入实际的调用序列。例如。对于支持两个指令集的体系结构,只要调用者和被调用者使用的指令集不同,就需要插入“指令集开关”。
链接器优化可以基于与体系结构相关的细节。例如。如果4KB区域内的函数调用更快,那么将调用者和被调用者放在一起是有意义的。
可以完成对象文件的内联,但需要删除调用设置,被调用者序言,被调用者epilog和返回值处理。这些是特定于体系结构的,因此只需识别它们就已经采用了特定于架构的链接器。
答案 1 :(得分:4)
不同的体系结构在其指令中具有不同的地址格式,链接器必须知道这些格式才能操作它们。
相对寻址可能会导致不同的指令,具体取决于相对地址的大小。
还存在更复杂的方案,例如ARM。
通常在链接器格式规范的补充中对其进行描述,例如,查看从this Wikipedia article on the ELF format链接的文档。
答案 2 :(得分:1)
要解析地址,链接器至少需要知道地址的字节序和大小。某些体系结构(如x86实模式)具有相当复杂的寻址方案,有些在地址中嵌入了地址,因此链接器可能需要知道地址或偏移字段。
答案 3 :(得分:0)
可以构建一些链接器来理解多种体系结构。例如,我为我的交叉编译器项目http://ellcc.org使用gnu ld,gdb,binutils和汇编程序。我有一个特定于每个目标的汇编程序,但链接器,调试器和binutils都了解所有处理器。支持的处理器种类繁多:ARM,CellSPU,Mips,MSP430,Nios2,PIC16,PowerPC,PowerPC64,Sparc,X86,X86_64。
答案 4 :(得分:0)
构建了一些工具链,以便在整个程序信息可用时,将大部分优化推迟到链接时。内联,常量传播和许多其他传统优化的好处在应用于整个二进制文件时最适用,而不仅仅是每个对象。