我一直在想.我知道编译器会将您编写的代码转换为二进制文件,但链接器的作用是什么?对我来说,它们一直是个谜.
我粗略地理解'链接'是什么.当对库和框架的引用添加到二进制文件时.除此之外我什么都不懂.对我来说它"只是有效".我也理解动态链接的基础知识,但没有太深入.
有人可以解释这些条款吗?
64位Linux默认使用小内存模型,它将所有代码和静态数据置于2GB地址限制之下.这可确保您可以使用32位绝对地址.较旧版本的gcc使用静态数组的32位绝对地址,以便为相对地址计算保存额外的指令.但是,这不再有效.如果我尝试在汇编中创建一个32位的绝对地址,我会收到链接器错误:"在创建共享对象时,不能使用".data"重定位R_X86_64_32S;使用-fPIC重新编译".当然,此错误消息具有误导性,因为我没有创建共享对象,-fPIC也没有帮助.到目前为止我发现的是:gcc版本4.8.5对静态数组使用32位绝对地址,gcc版本6.3.0不使用.版本5可能也没有.binutils 2.24中的链接器允许32位绝对地址,而2.28则不允许.
这种变化的后果是必须重新编译旧库并破坏传统汇编代码.
现在我想问一下:这个改变是什么时候做的?它在某处记录了吗?是否有一个链接器选项,使其接受32位绝对地址?
我正在尝试将“main”的地址加载到 GNU 汇编器中的寄存器 (R10) 中。我没办法。在这里,我有什么和我收到的错误消息。
main:
lea main, %r10
Run Code Online (Sandbox Code Playgroud)
我还尝试了以下语法(这次使用 mov)
main:
movq $main, %r10
Run Code Online (Sandbox Code Playgroud)
使用以上两种方法,我都会收到以下错误:
/usr/bin/ld: /tmp/ccxZ8pWr.o: relocation R_X86_64_32S against symbol `main' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
使用 -fPIC 编译不能解决问题,只会给我同样的错误。
我在反汇编程序(浮点逻辑c ++)中找到了以下汇编代码。
842: movss 0x21a(%rip),%xmm0
Run Code Online (Sandbox Code Playgroud)
我知道,当进程rip将一直为842且此0x21a(%rip)将为const。使用该寄存器似乎有些奇怪。
我想知道使用rip相对地址代替其他寻址有什么好处。
x86-64 ×3
assembly ×2
gcc ×2
att ×1
c++ ×1
disassembly ×1
linker ×1
linux ×1
relocation ×1
x86 ×1