macos 无法使用 ld 在 Mac OS X 中链接程序集文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6957488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't link assembly file in Mac OS X using ld
提问by Hyman Greenhill
I'm trying to run a basic assembly file using 64 Bit Mac OS X Lion, using nasm and ld which are installed by default with Xcode.
我正在尝试使用 64 位 Mac OS X Lion,使用 nasm 和 ld 运行基本程序集文件,这些文件在 Xcode 中默认安装。
I've written an assembly file, which prints a character, and I got it to build using nasm.
我写了一个汇编文件,它打印了一个字符,我使用 nasm 来构建它。
nasm -f elf -o program.o main.asm
nasm -f elf -o program.o main.asm
However, when I go to link it with ld, it fails with quite a few errors/warnings:
但是,当我将它与 ld 链接时,它失败并出现很多错误/警告:
ld -o program program.o
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
So, I tried to rectify a few of these issues, and got nowhere.
所以,我试图纠正其中的一些问题,但一无所获。
Here's one of things I've tried:
这是我尝试过的一件事:
ld -arch i386 -e _start -o program program.o
ld -arch i386 -e _start -o program program.o
Which I thought would work, but I was wrong.
我认为这会奏效,但我错了。
How do you make the object file a compatible architecture that nasm and ld will agree with?
Also, how would you define the entry point in the program (right now I'm using global _start
in .section text
, which is above _start
, which doesn't seem to do much good.)
您如何使目标文件成为 nasm 和 ld 同意的兼容架构?
另外,您将如何定义程序中的入口点(现在我正在使用global _start
in .section text
,它在上面_start
,这似乎并没有多大用处。)
I'm a bit confused as to how you would successfully link an object file to a binary file using ld, and I think I'm just missing some code (or argument to nasm or ld) that will make them agree.
我对如何使用 ld 成功地将目标文件链接到二进制文件感到有些困惑,我想我只是缺少一些使他们同意的代码(或 nasm 或 ld 的参数)。
Any help appreciated.
任何帮助表示赞赏。
回答by Shirkrin
OK, looking at your samples I assume you either used a generic nasm or linux assembly tutorial.
The first thing you need to take care of is the binary format created by nasm.
Your post states:
好的,查看您的示例,我假设您使用了通用的 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)
Thats the result of the '-f elf'parameter which tells nasm you want a 32bit ELF object (which would be the case for e.g. linux). But since you're on OSX what you want is a Mach-O object.
这就是' -f elf'参数的结果,它告诉nasm你想要一个32位的ELF对象(例如linux就是这种情况)。但既然你在 OSX 上,你想要的是 Mach-O 对象。
Try the following:
请尝试以下操作:
nasm -f macho64 -o program.o main.asm
gcc -o program program.o
Or if you wan't to create a 32bit binary:
或者,如果您不想创建 32 位二进制文件:
nasm -f macho32 -o program.o main.asm
gcc -m32 -o program program.o
Regarding the _startsymbol - if you wan't to create a simple program that will be able to use the provided libc system functions then you shouldn't use _startat al. It's the default entry point ldwill look for and normaly it's provided in your libc / libsystem.
关于_start符号 - 如果您不想创建一个能够使用所提供的 libc 系统函数的简单程序,那么您根本不应该使用_start。这是ld将查找的默认入口点,通常它在您的 libc/libsystem 中提供。
I suggest you try to replace the _startin your code by something like '_main'and link it like the example above states.
我建议您尝试将代码中的_start替换为“_main”之类的内容,并像上面的示例一样链接它。
A generic libc-based assembly template for nasm could look like this:
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
In addition to this I should mention that any call's you do on OSX need to use an aligned stack frame or your code will just crash.
There are some good tutorials on that out there too - try searching for OSX assembly guide.
除此之外,我应该提到您在 OSX 上进行的任何调用都需要使用对齐的堆栈帧,否则您的代码将崩溃。
那里也有一些很好的教程 - 尝试搜索 OSX 程序集指南。
回答by mk12
You need to use global start
and start:
, no underscore. Also, you should not be using elf
as the arch. Here is a bash script I use to assemble my x86-64 NASM programs on Mac OS X:
您需要使用global start
和start:
,没有下划线。此外,您不应该elf
用作拱门。这是我用来在 Mac OS X 上组装 x86-64 NASM 程序的 bash 脚本:
#!/bin/bash
if [[ -n "" && -f "" ]]; then
filename=""
base="${filename%%.*}"
ext="${filename##*.}"
nasm -f macho64 -Ox "$filename" \
&& ld -macosx_version_min 10.7 "${base}.o" -o "$base"
fi
If you have a file called foo.s
, this script will first run
如果您有一个名为 的文件foo.s
,则此脚本将首先运行
nasm -f macho64 -Ox foo.s
Which will create foo.o
. The -Ox
flag makes NASM do some extra optimization with jumps (i.e. making them short, near or far) so that you don't have to do it yourself. I'm using x86-64, so my code is 64-bit, but it looks like you're trying to assemble 32-bit. In that case, you would use -f macho32
. See nasm -hf
for a list of valid output formats.
这将创建foo.o
. 该-Ox
标志使 NASM 对跳跃进行一些额外的优化(即使它们变短、变近或变远),这样您就不必自己做。我使用的是 x86-64,所以我的代码是 64 位的,但看起来您正在尝试组装 32 位。在这种情况下,您将使用-f macho32
. 有关nasm -hf
有效输出格式的列表,请参见。
Now, the object file will be linked:
现在,目标文件将被链接:
ld -macosx_version_min 10.7 foo.o -o foo
I've set the -macosx_version_min
option to quiet NASM down and prevent a warning. You don't have to set it to Lion (10.7). This will create an executable called foo
. With any luck, typing ./foo
and hitting return should run your program.
我已经设置了-macosx_version_min
使 NASM 安静并防止警告的选项。您不必将其设置为 Lion (10.7)。这将创建一个名为foo
. 运气好的话,输入./foo
并按回车键应该会运行你的程序。
In regard to the ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib
warning, I get that every time too and I'm not sure why, but everything seems fine when I run the executable.
关于ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib
警告,我也每次都收到,但我不知道为什么,但是当我运行可执行文件时,一切似乎都很好。
回答by Paul R
It's probably easier just to let gcc
do the heavy lifting for you, rather than trying to drive ld
directly, e.g.
让gcc
你为你做繁重的工作可能更容易,而不是试图ld
直接开车,例如
$ gcc -m32 program.o -o program
回答by scubasteve623
The mac gcc compiler won't link elf objects. You need a cross compiler...
mac gcc 编译器不会链接 elf 对象。你需要一个交叉编译器...
http://crossgcc.rts-software.org/doku.php?id=compiling_for_linux
http://crossgcc.rts-software.org/doku.php?id=compiling_for_linux
Then you can proceed with something similar to this...
然后你可以继续进行类似的事情......
/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