X86 64位汇编Linux' Hello World'关联问题

时间:2017-01-25 06:43:01

标签: c linux assembly x86-64

我试图跟进this thread,遗憾的是,这并不能解决我的问题。我试图运行的代码如下:

; File hello.asm

        section .data
msg:    db      "Hello World!",0x0a,0

        section .text
        global main
        extern printf

main:
        push  rbp
        mov   rbp, rsp
        lea   rdi, [msg]  ; parameter 1 for printf
        xor   eax, eax    ; 0 floating point parameter
        call  printf
        xor   eax, eax    ; returns 0
        pop   rbp
        ret

我的系统是debian stretch:

$ uname -a
Linux <host> 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux

我正在使用yasm汇编程序,如下所示:

$ yasm -f elf64 -g dwarf2 hello.asm

由于我在上述来源中的切入点是main并且有最终ret条指令,因此我猜我需要与gcc而不是ld -e main相关联:

$ gcc -lc hello.o

但是,我收到以下错误消息:

/usr/bin/ld: hello.o: relocation R_X86_64_32 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

此错误提到了使用-fPIC重新编译的内容,但这是gcc编译器选项,而不是汇编程序yasm的有效选项。所以我不知道该怎么做。

为了测试,我试图与ld

进行链接
$ ld -e main -lc hello.o

这是成功的,但我在运行时获得了与上述线程中提到的相同的错误:

$ ./a.out
bash: ./a.out: No such file or directory       # The file *is* there ...

(根据线程的答案,我试图将.so二进制文件中提到的ld库与我的系统库进行比较,它们都是{{1} }。)

我还尝试用/lib64/ld-linux-x86-64.so.2替换main入口点(暂时忘记正确退出程序的问题)并与_start链接但我收到同样的错误& #39;没有这样的文件或目录&#39;像之前一样。我会继续玩这个,但我想也会问。

任何有效的建议(ld -lc hello.omain_startgcc)都会受到热烈赞赏。

修改 正如Jim所建议的那样,我在ld的顶部添加了default rel,并在与gcc链接时获得了不同的错误消息(hello.asm无更改)

ld -e main -lc

EDIT2:这篇文章与$ gcc -lc hello.o /usr/bin/ld: hello.o: relocation R_X86_64_PC32 against symbol `printf@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Bad value collect2: error: ld returned 1 exit status 失败有关:

debian stretch

关注Jim的评论我刚刚在 Linux: 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux yasm: 1.3.0 gcc: (Debian 6.2.1-5) 6.2.1 20161124 ld: GNU ld (GNU Binutils for Debian) 2.27.51.20161220 上测试了相同的代码,这些代码完全正常debian jessie和以下版本:

gcc -lc hello.o

编辑3:等待Michael Petch的正式回答:问题解决 Linux: 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux yasm: 1.2.0 gcc: (Debian 4.9.2-10) 4.9.2 ld: GNU ld (GNU Binutils for Debian) 2.25

1 个答案:

答案 0 :(得分:8)

Debian Stretch defaults to building position independent executables中的GCC,用于构建链接到特定地址的可执行文件,就像传统的-no-pie传递给GCC一样。

或者指定正确的重定位类型,我不知道如何在yasm中执行此操作。