我正在尝试使用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
,这似乎没有太大的好处。)
关于如何使用ld成功将目标文件链接到二进制文件,我有点困惑,我想我只是缺少一些会让他们同意的代码(或者对nasm或ld的参数)。
任何帮助赞赏。
好的,看看你的样本我假设你使用了通用的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)
多数民众赞成的结果 “ - 小精灵“ 告诉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
关于 _开始 符号 - 如果你不想创建一个能够的简单程序
使用提供的libc系统功能,你不应该使用 _开始 在al。
这是默认入口点 LD 将在您的libc / libsystem中提供并寻找它。
我建议你尝试更换 _开始 在您的代码中通过类似的东西 '_主要'
并像上面的例子那样链接它。
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汇编指南。
你需要使用 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
flag使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
警告,我每次都得到它,我不知道为什么,但是当我运行可执行文件时,一切似乎都很好。
让它变得更容易 gcc
为你做繁重的工作,而不是试图开车 ld
直接地,例如
$ gcc -m32 program.o -o program
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