当前位置:  开发笔记 > 编程语言 > 正文

X86 64位汇编Linux"Hello World"链接问题

如何解决《X8664位汇编Linux"HelloWorld"链接问题》经验,为你挑选了1个好方法。

我试图跟进这个线程,遗憾的是它并没有完全解决我的问题.我试图运行的代码如下:

; 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  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 ...

(根据线程的答案,我试图.sold二进制文件中提到的库与我的系统库进行比较,它们都是/lib64/ld-linux-x86-64.so.2.)

我还尝试main_start(忘记现在正确退出程序的问题)替换入口点并链接ld -lc hello.o但是我得到了与之前相同的错误"没有这样的文件或目录".我会继续玩这个,但我想也会问.

任何工作建议(与main_start,gccld)将受到热烈的赞赏.

编辑: 正如吉姆所建议的那样,我添加default rel了顶部,hello.asm并在与gcc链接时获得了不同的错误消息(没有更改ld -e main -lc)

$ 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

编辑2:这篇文章涉及到失败debian stretch:

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

继Jim的评论之后,我刚刚测试了相同的代码, debian jessie gcc -lc hello.o以下版本完美搭配:

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

编辑3:正在接受Michael Petch的正式回答:问题解决了 gcc -static hello.o



1> Timothy Bald..:

Debian Stretch中的GCC 默认构建位置无关的可执行文件,以构建链接到特定地址的可执行文件,这是传统的-no-pieGCC 传递.

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

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有