我正在尝试使用64位Mac OS X Lion运行一个基本的程序集文件,使用默认安装在Xcode上的nasm和ld。
我已经编写了一个汇编文件,可以打印一个字符,然后我使用nasm构建它。
nasm -f elf -o program.o main.asm
但是,当我将它与ld链接时,它会因为相当多的错误/警告而失败:
ld -o program program.o
ld: warning: -arch not specified
ld: warning: -macosx_version_min not specificed, assuming 10.7
ld: warning: ignoring file program.o, file was built for unsupported file format which is not the architecture being linked (x86_64)
ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib
ld: entry point (start) undefined. Usually in crt1.o for inferred architecture x86_64
所以,我试图解决其中的一些问题,并没有取得任何进展。
这是我尝试过的一件事:
ld -arch i386 -e _start -o program program.o
我认为这会奏效,但我错了。
如何使目标文件成为nasm和ld同意的兼容架构?
另外,你如何定义程序中的入口点(现在我在global _start
使用.section text
,_start
以上{{1}}似乎做得很好。)
关于如何使用ld成功将目标文件链接到二进制文件,我有点困惑,我想我只是缺少一些会让他们同意的代码(或者是nasm或ld的参数)。
任何帮助表示感谢。
答案 0 :(得分:5)
好的,看看你的样本我假设你使用了通用的nasm或linux汇编教程 您需要注意的第一件事是由nasm创建的二进制格式 你的帖子说明:
ld: warning: ignoring file program.o, file was built for unsupported file format which is not the architecture being linked (x86_64)
这是' -f elf '参数的结果,它告诉nasm你想要一个32位ELF对象(例如linux的情况)。但是,因为你在OSX上你想要的是一个Mach-O对象。
尝试以下方法:
nasm -f macho64 -o program.o main.asm
gcc -o program program.o
或者如果您不想创建32位二进制文件:
nasm -f macho32 -o program.o main.asm
gcc -m32 -o program program.o
关于 _start 符号 - 如果您不想创建一个能够执行的简单程序 要使用提供的libc系统功能,你不应该在al使用 _start 。 这是 ld 将在libc / libsystem中提供的默认入口点。
我建议您尝试用'_ main'替换代码中的 _start 并像上面的例子那样链接它。
nasm的基于libc的通用程序集模板可能如下所示:
;---------------------------------------------------
.section text
;---------------------------------------------------
use32 ; use64 if you create 64bit code
global _main ; export the symbol so ld can find it
_main:
push ebp
mov ebp, esp ; create a basic stack frame
[your code here]
pop ebp ; restore original stack
mov eax, 0 ; store the return code for main in eax
ret ; exit the program
除此之外,我应该提一下,你在OSX上做的任何调用都需要使用对齐的堆栈帧,否则你的代码就会崩溃。
这里有一些很好的教程 - 尝试搜索OSX汇编指南。
答案 1 :(得分:5)
您需要使用global start
和start:
,无下划线。此外,您不应该使用elf
作为拱门。这是我用来在Mac OS X上组装我的x86-64 NASM程序的bash脚本:
#!/bin/bash
if [[ -n "$1" && -f "$1" ]]; then
filename="$1"
base="${filename%%.*}"
ext="${filename##*.}"
nasm -f macho64 -Ox "$filename" \
&& ld -macosx_version_min 10.7 "${base}.o" -o "$base"
fi
如果您有一个名为foo.s
的文件,则此脚本将首先运行
nasm -f macho64 -Ox foo.s
将创建foo.o
。 -Ox
标志使NASM通过跳跃进行一些额外的优化(即使它们短,近或远),这样你就不必自己动手了。我使用的是x86-64,所以我的代码是64位,但看起来你正试图组装32位。在这种情况下,您将使用-f macho32
。有关有效输出格式的列表,请参阅nasm -hf
。
现在,目标文件将被链接:
ld -macosx_version_min 10.7 foo.o -o foo
我已将-macosx_version_min
选项设置为静音NASM并阻止警告。您不必将其设置为Lion(10.7)。这将创建一个名为foo
的可执行文件。运气好的话,输入./foo
并点击返回应该运行你的程序。
关于ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib
警告,我每次都会得到这个警告,但我不确定原因,但是当我运行可执行文件时,一切似乎都很好。
答案 2 :(得分:2)
让gcc
为你做繁重的工作可能更容易,而不是试图直接驾驶ld
,例如。
$ gcc -m32 program.o -o program
答案 3 :(得分:1)
mac gcc编译器不会链接elf对象。你需要一个交叉编译器......
http://crossgcc.rts-software.org/doku.php?id=compiling_for_linux
然后你可以继续进行类似的事情......
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-ld -m elf_i386 -T link.ld -o kernel kasm.o kc.o