0

hello.asmを Windows 実行可能ファイルにビルドしようとしていますが、推奨されるコマンドを使用してコードをアセンブル、リンク、およびコンパイルすると、エラーが発生します。Strawberry Perlの GCCを使用しているかMinGWの GCC を使用しているかにかかわらず、どちらも同じ YASM/NASM コードに対してエラーを返します。

ここに痕跡があります。Makefile または .ASM で何か間違ったことを行っているか、リンク プロセスにバグがあります。いずれにせよ、誰かにエラーの解決を手伝ってもらいたいです。

nasm と yasm のどちらを使用してオブジェクト ファイルをアセンブルしても、同じ結果が得られます。

ストロベリー Perl GCC トレース:

C:\> make
nasm -f win32 -l hello.lst hello.asm
gcc -o hello hello.o
ld: cannot find crt1.o: No such file or directory
ld: cannot find -lmingw32
ld: cannot find -lgcc
ld: cannot find -lmoldname
ld: cannot find -lcrtdll
ld: cannot find -luser32
ld: cannot find -lkernel32
ld: cannot find -ladvapi32
ld: cannot find -lshell32
ld: cannot find -lmingw32
ld: cannot find -lgcc
ld: cannot find -lmoldname
ld: cannot find -lcrtdll
make: *** [hello] Error 1

MinGW GCC トレース:

$ make
gcc -o hello hello.o
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0x104): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
make: *** [hello] Error 1

仕様:

  • YASM 1.2.0
  • NASM 2.10.05
  • ストロベリーパール gcc 4.4.3
  • MinGW gcc 4.5.2
  • ストロベリーパール5.12
  • MinGW 0.1
  • Windows 7 プロフェッショナル x64
  • MacBook Pro 2009
4

3 に答える 3

4

関数を次のようmain()にラベルに置き換えます。_WinMain@16

main.asm

    section .text
    extern  _foo

;--------------------------------------------------
; main()
; 在 Win32 環境下, _WinMain@16 為程式進入點
;--------------------------------------------------

    global  _WinMain@16
_WinMain@16:
    ; foo(2,3)
    ; 呼叫時, 參數為堆疊順序 (先進後出)
    push    DWORD 3     ; b=3
    push    DWORD 2     ; a=2
    call    _foo

    ; 堆疊復原
    pop     eax
    pop     eax
    ret

foo.c

    #include <stdio.h>

    void foo(int a, int b) {
         printf("%d + %d = %d\n", a, b, a+b);
    }

メイクファイル

all:
    rm -f *.o
    gcc -c foo.c
    nasm -f win32 -o main.o main.asm
    gcc -o main.exe main.o foo.o
于 2012-11-22T07:59:28.620 に答える
1

いくつかの部分からなるソリューション:

  1. 奇妙なことが起こっgcc ...ていました。実行可能ファイルをビルドするために手動で入力すると、ほとんどリンク エラーが発生しません。しかしmake、まったく同じコマンドを実行すると、あらゆる種類のリンク エラーが発生しました。Free Pascal の make.exe が適切な make.exe を隠していたことが判明しました。これを修正するには、PATH で適切なディレクトリを昇格するか、問題のあるアプリケーションをアンインストールします。私は Pascal をあまり使用していなかったので、アンインストールしたところ、突然 gcc の動作が改善されました。

  2. Windows NASM/YASM アセンブリでは、関数名の前にアンダースコア ( _) を付ける必要があります。アセンブリ コードをマルチプラットフォームに保つには、コード内のアンダースコアを省略し、Makefile オプションを使用して、Windows でビルドするときにアンダースコアを先頭に付けるように nasm/yasm に指示します。

  3. Windows でそれらをリンクするための手動ld呼び出しによるビルドは機能しません。gccGCC はどうにかしてこれを整理する方法を知っているため、置換によって奇妙な「未定義の printf」リンク エラーが修正されました。

  4. 特にマルチプラットフォームの場合、プログラムを適切に終了するのは困難です。1 つの方法は、eaxゼロに設定してから返すことです。

これらはすべて、GitHub にあるNASMおよびYASMの hello.asm の作業バージョンに反映されています。

于 2012-09-20T18:44:03.833 に答える
0

単純な Windows コンソール hello の場合: hello.asm

extern  printf, ExitProcess

SECTION     .data
szHello db  "Hello there!", 0

SECTION     .text
StartHello:
    push    szHello
    call    printf
    add     esp, 4 

    push    0
    call    ExitProcess 

メイクファイル:

hello: hello.obj
    GoLink.exe  /console /entry StartHello hello.obj kernel32.dll msvcrt.dll  

hello.obj: hello.asm
    nasm -f win32 hello.asm -o hello.obj
于 2012-09-20T02:29:50.600 に答える