Gcc 尝试链接nasm对象文件时链接失败

Gcc 尝试链接nasm对象文件时链接失败,gcc,x86,nasm,x86-64,ld,Gcc,X86,Nasm,X86 64,Ld,我有一个简单的程序来计算浮点数的平方根 global main extern printf section .data float_t db '%f',0x0 val dq 123.45 res dq 0x0 section .text main: fld qword[val] fsqrt fst qword[res] xor rax,rax mov rdi, floa

我有一个简单的程序来计算浮点数的平方根

global main
extern printf
section .data
        float_t db '%f',0x0
        val dq 123.45
        res dq 0x0
section .text
main:
        fld qword[val]
        fsqrt
        fst qword[res]
        xor rax,rax
        mov rdi, float_t
        mov rsi, [res]
        call printf
        mov rax,60
        mov rdi,0
        syscall
我自己组装的

$  nasm -f elf64 fpu.asm -o fpu.o
然后尝试以gcc作为链接到glibc

$  gcc fpu.o -o fpu
GCC投诉:

/usr/bin/ld: fpu.o: relocation R_X86_64_32S against `.data' 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

正如Michael Petch在上述评论中所述

我希望使用
-静态
的建筑可以工作


我也有同样的问题,这就解决了。

正如迈克尔·佩奇在上面的评论中所说

我希望使用
-静态
的建筑可以工作


我也有同样的问题,这就解决了。

什么操作系统(Linux)和版本?该错误表明用于构建可执行文件的命令行(使用GCC)正在使用
-shared
选项。您可以尝试使用
-static
选项构建。我怀疑您使用的Linux发行版基于Ubuntu 16.10及更高版本,或者是最新的Debian(测试版本)。@MichaelPetch我使用的是Debian sid。是的,我怀疑可能是测试版或不稳定版本。Ubuntu 16.10及更高版本(以及Debian测试和sid)默认情况下构建位置无关的对象和可执行文件(在64位平台上)。我希望使用
-静态
构建可能会起作用。@MichaelPetch,这应该是一个(被接受的)答案。这个例子有很多错误(你还没有得到调试的机会,因为你被链接卡住了。)
printf
在XMM注册表中按值取一个
double
(AL=1),不是指针。什么操作系统(Linux)和版本?该错误表明用于构建可执行文件的命令行(使用GCC)正在使用
-shared
选项。您可以尝试使用
-static
选项构建。我怀疑您使用的Linux发行版基于Ubuntu 16.10及更高版本,或者是最新的Debian(测试版本)。@MichaelPetch我使用的是Debian sid。是的,我怀疑可能是测试版或不稳定版本。Ubuntu 16.10及更高版本(以及Debian测试和sid)默认情况下构建位置无关的对象和可执行文件(在64位平台上)。我希望使用
-静态
构建可能会起作用。@MichaelPetch,这应该是一个(被接受的)答案。这个例子有很多错误(你还没有得到调试的机会,因为你被链接卡住了。)
printf
在XMM注册表中按值取一个
double
(AL=1),不是指针。
-no pie
会比
-static
@PeterCordes更好,我必须检查一下。为什么会这样?因为您不需要静态链接libc,如果查看
objdump-drwC-Mintel
输出,就会使可执行文件膨胀,并使查找自己的代码变得更加困难<代码>-没有饼图
足以让链接器自动生成PLT存根并用
调用替换
调用printf
printf@plt
。IDK为什么它不为PIE可执行文件这样做;也许这是PIE可执行文件是某种共享库这一事实的副作用。另请参见
-没有饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼状饼。为什么会这样?因为您不需要静态链接libc,如果查看
objdump-drwC-Mintel
输出,就会使可执行文件膨胀,并使查找自己的代码变得更加困难<代码>-没有饼图
足以让链接器自动生成PLT存根并用
调用替换
调用printf
printf@plt
。IDK为什么它不为PIE可执行文件这样做;也许这是PIE可执行文件是某种共享库这一事实的副作用。另见