ZHCU947E June 2015 – January 2023
汇编器在处理每一个段时均假设它始于地址 0。当然,在存储器中不可能所有段都始于地址 0,因此链接器必须将段重定位。重定位与符号相关,而不是与段相关。
链接器将段重定位的方式是:
链接器使用重定位条目调整对符号值的引用。汇编器在可重定位的符号被引用时会创建一个重定位条目。然后链接器会使用这些条目在符号重新定位后修补引用。以下示例包含 TMS320C6000 器件的代码片断,汇编器会针对它们生成重定位条目。
1 .global X
2 00000000 00000012! Z: B X ; Uses an external relocation
3 00000004 0180082A' MVKL Y,B3 ; Uses an internal relocation
4 00000008 0180006A' MVKH Y,B3 ; Uses an internal relocation
5 0000000C 00004000 NOP 3
6
7 00000010 0001E000 Y: IDLE
8 00000014 00000212 B Y
9 00000018 00008000 NOP 5
在以上示例中,符号 X 和 Y 均可重定位。Y 在本模块的 .text 段中定义;X 在另一模块中定义。汇编代码时,X 的值为 0(汇编器假定所有未定义的外部符号的值均为 0),Y 的值为 16。汇编器生成两个重定位条目:一个用于 X,一个用于 Y。对 X 的引用是外部引用(由列表中的 ! 字符表示)。对 Y 的引用是对内部定义的可重定位符号的引用(由列表中的 ' 字符表示)。
链接代码后,假设将 X 重定位到地址 0x7100。再假设将 .text 段重定位为从地址 0x7200 开始;Y 目前的重定位值为 0x7210。链接器使用两个重定位条目来修补目标代码中的两个引用:
|
becomes |
|
|
becomes |
|
|
becomes |
|
重定位与符号相关,而不是与段相关。这意味着上述示例中为“Y”生成的重定位会引用符号“Y”,并在“Y”的定义结束时解析操作码中的“Y”值。