将Linux x86-64程序集hello world程序与ld链接失败

我一直在最近在linux上玩x86 64程序集,然后在编译一个看起来很简单的程序后,我留下了我的脑袋:P

虽然我编译和链接它没有引发错误,并产生一个Linux ELF当我尝试运行它,我得到:

.:[ h4unt3r@sp3ctr4l-h0st asm ]:. #(0)> ./hello bash: ./hello: No such file or directory 

我假设它产生一个无效的ELF文件,这就是为什么它报告你不在那里,即使它是。 不知道为什么 – 我可能会继续玩它,只是好奇,如果这可以轻松解决^ _ ^

这是我的编译/链接命令行:

 nasm -f elf64 hello.s -g ld -o hello hello.o -lc 

这里是代码:

 section .data msg: db "Hello, world!",0xa,0 section .text extern printf global main main: push rbp mov rbp, rsp mov rdi, msg xor rax, rax call printf xor rax, rax pop rbp ret 

编辑 – 我不想使用gcc 🙂

我正在运行32位硬件,不能测试64位的东西。 我在32位代码中看到这个“没有这样的文件”的错误。 默认情况下,ld使用“/lib/ld-linux.so.1” – 你可以在可执行文件中以纯文本的形式看到这个字符串。 这是不存在的文件(显然“你好”就在那里!)。 解决办法是告诉ld -I/lib/ld-linux.so.2 。 我怀疑类似的解决方案将适用于64位,但我不知道你需要什么“解释器”或“动态链接器”。 尝试在可执行文件中查找类似的字符串,并在您的库中查找类似的.so。 你不应该“需要”使用海湾合作委员会…但海湾合作委员会知道在哪里可以找到这个东西! 可能会更容易使用它。 这是一个令人困惑的错误,不是吗?

(我希望你的入口点是_start ,而不是main如果你打算这样做的话,你将无法从这里退出 – 使用sys_exit或exit()。)

我不熟悉关于“符号表0”的错误nrz提到。 当然不是故意改变Nasm! Nasm开发者在http://www.nasm.us上或周围闲逛,很高兴听到反馈和错误报告。 (好吧,也许不是对bug报告“高兴”。)我会看看我能不能找出任何东西…

FWIW,Nasm默认仅使用-g开关“刺入”调试信息。 要启用“矮人”调试信息, -F dwarf …假设工作更好…

首先,要使用printf ,你需要使用gcc而不是ld链接:

 gcc -o hello hello.o 

那么,另外一个问题可能和我自己遇到的一样。 我不确定这是NASM的一个错误还是一个预期的改变:

 user @ computer:〜/ code / asm $ nasm -f elf64 hello.asm -g;  gcc -o你好hello.o
 / usr / bin / ld:错误:重定位部分9使用意外符号表0
 collect2:错误:ld返回1退出状态

我已经解决了这个问题,转移到YASM ,并进行组装和链接:

 yasm -f elf64 hello.s -g dwarf2 gcc -o hello hello.o 

其中生成一个可执行文件与预期的输出:

 ./hello Hello, world! 

修改一下这个代码。

 section .data msg: db "Hello, world!",0xa,0 section .text extern printf global main main: push rbp mov rbp, rsp mov rdi,msg xor rax,rax call printf xor rax,rax pop rbp mov rax,60 ; use exit syscall mov rdi,0 ; error code 0 syscall ; call kernel 

并使用

ld -e main hello.o -o hello -lc –dynamic-linker /lib64/ld-linux-x86-64.so.2