【问题标题】:Can't link assembly file in Mac OS X using ld无法使用 ld 在 Mac OS X 中链接程序集文件
【发布时间】:2011-10-20 21:53:17
【问题描述】:


我正在尝试使用 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 同意的兼容架构?

另外,你将如何定义程序中的入口点(现在我在.section text 中使用global _start,它在_start 之上,这似乎没有多大用处。 )

对于如何使用 ld 成功地将目标文件链接到二进制文件,我有点困惑,而且我认为我只是缺少一些代码(或 nasm 或 ld 的参数),这将使他们同意。

任何帮助表示赞赏。

【问题讨论】:

  • 您是否尝试过使用 gcc 而不是 ld 进行链接?它通常要容易得多,您可以使用 C 运行时和标准库(例如,将 main 作为入口点)。要尝试的另一件事是使用mach 对象文件格式而不是elf

标签: macos assembly nasm ld object-files


【解决方案1】:

gcc 为您完成繁重的工作可能比直接驾驶ld 更容易,例如

$ gcc -m32 program.o -o program

【讨论】:

    【解决方案2】:

    好的,看看您的示例,我假设您使用了通用 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 系统函数,那么您不应该使用 _start 。 这是默认的入口点 ld 将在您的 libc / libsystem 中查找并正常提供它。

    我建议您尝试将代码中的 _start 替换为 '_main' 并像上面的例子一样链接它。

    用于 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 组装指南。

    【讨论】:

      【解决方案3】:

      你需要使用global startstart:没有下划线。此外,您不应该使用 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 警告,我也每次都收到,但我不知道为什么,但是当我运行可执行文件时一切似乎都很好。

      【讨论】:

        【解决方案4】:

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-23
          • 2010-11-04
          • 2011-01-04
          • 1970-01-01
          • 2012-12-14
          • 1970-01-01
          • 2013-12-17
          相关资源
          最近更新 更多