我最近在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:)
答案 0 :(得分:4)
我正在运行32位硬件,无法测试64位内容。我在32位代码中看到了这个“没有这样的文件”错误。默认情况下,ld使用“/lib/ld-linux.so.1” - 您可以在可执行文件中以纯文本形式查看此字符串。这是不存在的文件(显然“你好”就在那里!)。解决方案是告诉ld -I/lib/ld-linux.so.2
。我怀疑类似的解决方案适用于64位,但我不知道你需要什么“解释器”或“动态链接器”。尝试在可执行文件中查找类似的字符串,并在libs中查找类似的.so。你不应该“需要”使用gcc ......但是gcc知道在哪里可以找到这些东西!可能更容易使用它。看到一个令人困惑的错误,不是吗?
(我希望你的入口点为_start
,而不是main
,如果你打算这样做。你将无法ret
从这里开始 - 使用sys_exit或exit()。)
我不熟悉nrz提到的关于“符号表0”的错误。当然不是故意改变纳斯姆! Nasm开发人员在http://www.nasm.us或其周围闲逛,很高兴听到那里的反馈和错误报告。 (好吧,或许对bug报告并不“高兴”。)我会看看能不能找到任何东西......
FWIW,Nasm默认只用-g
开关“刺”调试信息。要启用“矮人”调试信息,-F dwarf
...假设工作得更好......
答案 1 :(得分:3)
首先,要使用printf
,您需要与gcc
而不是ld
建立关联:
gcc -o hello hello.o
然后,另一个问题可能与我遇到的情况相同。我不确定这是NASM中的错误还是预期的变化:
user@computer:~/code/asm$ nasm -f elf64 hello.asm -g; gcc -o hello hello.o /usr/bin/ld: error: relocation section 9 uses unexpected symbol table 0 collect2: error: ld returned 1 exit status
我已经解决了这个问题,转移到YASM,并以这种方式进行汇编和链接:
yasm -f elf64 hello.s -g dwarf2
gcc -o hello hello.o
生成具有预期输出的可执行文件:
./hello
Hello, world!
答案 2 :(得分:2)
稍微修改一下代码。
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