12


デフォルトでXcodeにインストールされているnasmとldを使用して、64ビットMac OS X Lionを使用して基本的なアセンブリファイルを実行しようとしています。

文字を出力するアセンブリ ファイルを作成し、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

そのため、これらの問題のいくつかを修正しようとしましたが、どこにも行きませんでした.

これが私が試したことの1つです:

ld -arch i386 -e _start -o program program.o

これはうまくいくと思っていましたが、間違っていました。

オブジェクト ファイルを、nasm と ld が一致する互換性のあるアーキテクチャにするにはどうすればよいでしょうか?

また、プログラムのエントリ ポイントをどのように定義しますか (現在、私は上記のglobal _startin を使用していますが、あまり効果がないようです)。.section text_start

ld を使用してオブジェクト ファイルをバイナリ ファイルに正常にリンクする方法について少し混乱しています。それらを一致させるコード (または nasm または ld への引数) が不足していると思います。

どんな助けでも感謝します。

4

4 に答える 4

6

アンダースコアglobal startを使用せずstart:に、を使用する必要があります。また、アーチとして使用しないでください。これは、MacOSXでx86-64NASMプログラムをアセンブルするために使用するbashスクリプトです。elf

#!/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 macho32nasm -hf有効な出力形式のリストについては、を参照してください。

これで、オブジェクトファイルがリンクされます。

ld -macosx_version_min 10.7 foo.o -o foo

-macosx_version_minNASMを静め、警告を防ぐオプションを設定しました。Lion(10.7)に設定する必要はありません。これにより、と呼ばれる実行可能ファイルが作成されfooます。運が良ければ、./fooreturnキーを押して入力すると、プログラムが実行されます。

警告に関してはld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib、私も毎回それを受け取り、理由はわかりませんが、実行可能ファイルを実行するとすべてが正常に見えます。

于 2011-12-30T18:33:06.140 に答える
5

OK、あなたのサンプルを見ると、一般的な 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 オブジェクトが必要であることを伝える' -f 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 at al を使用しないでください。これは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 アセンブリ ガイドを検索してみてください。

于 2011-09-15T07:29:27.627 に答える
2

直接gcc運転しようとするよりも、面倒な作業を任せた方がおそらく簡単です。ld

$ gcc -m32 program.o -o program
于 2011-08-05T14:13:51.037 に答える
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
于 2015-12-03T16:35:33.573 に答える