Jac*_*ill 11 macos assembly nasm ld object-files
我正在尝试使用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
Run Code Online (Sandbox Code Playgroud)
所以,我试图纠正其中的一些问题,并没有取得任何进展.
这是我尝试过的一件事:
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)
Run Code Online (Sandbox Code Playgroud)
这是' -f elf '参数的结果,它告诉nasm你想要一个32位ELF对象(例如linux的情况).但是,因为你在OSX上你想要的是一个Mach-O对象.
请尝试以下方法:
nasm -f macho64 -o program.o main.asm
gcc -o program program.o
Run Code Online (Sandbox Code Playgroud)
或者,如果您不想创建32位二进制文件:
nasm -f macho32 -o program.o main.asm
gcc -m32 -o program program.o
Run Code Online (Sandbox Code Playgroud)
关于_start符号 - 如果你不想创建一个能够使用提供的libc系统函数的简单程序,那么你不应该在al 使用_start.这是ld将在libc/libsystem中提供的默认入口点和normaly.
我建议你尝试用'_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
Run Code Online (Sandbox Code Playgroud)
除此之外,我应该提一下,你在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
Run Code Online (Sandbox Code Playgroud)
如果您有一个名为的文件foo.s,则该脚本将首先运行
nasm -f macho64 -Ox foo.s
Run Code Online (Sandbox Code Playgroud)
哪个会创造foo.o.该-Ox标志使NASM通过跳跃进行一些额外的优化(即使它们短,近或远),这样您就不必自己动手了.我使用的是x86-64,所以我的代码是64位,但看起来你正试图组装32位.在那种情况下,你会使用-f macho32.有关nasm -hf有效输出格式的列表,请参阅.
现在,目标文件将被链接:
ld -macosx_version_min 10.7 foo.o -o foo
Run Code Online (Sandbox Code Playgroud)
我已-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
Run Code Online (Sandbox Code Playgroud)