简体   繁体   English

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

[英]X86 64-bits Assembly Linux 'Hello World' linking issue

I am attempting to follow up on this thread which unfortunately does not quite solve my problem. 我试图跟进这个线程 ,遗憾的是它并没有完全解决我的问题。 The code I am trying to run is as follows: 我试图运行的代码如下:

; 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

My system is debian stretch: 我的系统是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

I am using the yasm assembler as follows: 我使用yasm汇编程序如下:

$ yasm -f elf64 -g dwarf2 hello.asm

Because my entry point in the above source is main with a final ret instruction, I am guessing I need to link with gcc rather than ld -e main : 因为在上面的源代码我的切入点是main用最后ret指令,我猜我需要链接gcc ,而不是ld -e main

$ gcc -lc hello.o

However, I am getting the following error message: 但是,我收到以下错误消息:

/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

This error mentions something about recompiling with -fPIC but this is a gcc compiler option, not a valid option of the assembler yasm . 此错误提到了有关使用-fPIC重新编译的内容,但这是gcc编译器选项,而不是汇编程序yasm的有效选项。 So I don't know what to do here. 所以我不知道该怎么做。

Just for the sake of testing, I have attempted to link with ld : 仅仅是为了测试,我试图与ld链接:

$ ld -e main -lc hello.o

which is successful, but I obtain the same error as mentioned in the above thread when running: 这是成功的,但我在运行时获得了与上述线程中提到的相同的错误:

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

(following the answer of the thread, I have attempted to compare the .so library mentioned in the ld binary file with my system's library, and they are both /lib64/ld-linux-x86-64.so.2 .) (根据线程的答案,我试图将ld二进制文件中提到的.so库与我的系统库进行比较,它们都是/lib64/ld-linux-x86-64.so.2 。)

I have also attempted to replace the main entry point with _start (forgetting the issue of properly exiting the program for now) and link with ld -lc hello.o but I get the same error 'No such file or directory' as before. 我还试图用_start替换main入口点(忘记现在正确退出程序的问题)并用ld -lc hello.o链接但是我得到了和以前一样的错误'没有这样的文件或目录'。 I will continue playing with this, but thought I would ask also. 我会继续玩这个,但我想也会问。

Any working suggestion (with main or _start , gcc or ld ) would be warmly appreciated. 任何工作建议(使用main_startgccld )都会受到热烈的赞赏。

EDIT: As suggested by Jim I have added default rel at the top of hello.asm and I obtain a different error message when linking with gcc (no change with ld -e main -lc ) 编辑:正如Jim所建议的那样,我在hello.asm的顶部添加了default rel ,并且在与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

EDIT2: This post relates to a failure on debian stretch : 编辑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

Following on Jim's comment I have just tested the same code on debian jessie which works perfectly fine with gcc -lc hello.o and the following versions: 继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

EDIT 3: Pending a formal answer from Michael Petch: issue resolved with gcc -static hello.o 编辑3:等待Michael Petch的正式回答: 问题解决了 gcc -static hello.o

GCC in Debian Stretch defaults to building position independent executables , to build executable linked to specific address as is traditional pass -no-pie to GCC. Debian Stretch中的GCC 默认构建位置无关的可执行文件 ,以构建链接到特定地址的可执行文件 ,就像传统的传递-no-pie到GCC一样。

Alternatively specify the correct relocation type, I don't know how to do this in yasm. 或者指定正确的重定位类型,我不知道如何在yasm中执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM