2

VS2010に付属しているMLとLINKを使用してWindowsでHelloWorldをコンパイルしようとしています。

.MODEL FLAT
.STACK 4096
.data
msg db "Hello World!",0
.code
INCLUDELIB MSVCRT
EXTRN printf:NEAR
EXTRN exit:NEAR
PUBLIC _main
_main PROC
mov eax, offset msg
push eax
call printf
mov eax,0
push eax
call exit
_main ENDP
END _main

printfとexitが未解決の外部シンボルであるというリンカーエラーが発生し続けます。いくつか質問があります。

  1. エラーメッセージをコンパイルおよび解決するためにMLおよびLINKで使用するコマンドラインオプションは何ですか。
  2. printfのようなcランタイム関数を呼び出すのではなく、アセンブリコードを使用してテキスト出力を画面に表示する別の方法はありますか?
4

1 に答える 1

4
  1. C関数には下線付きの名前を使用する必要があります。これは、コンパイラがアセンブリレベルでC関数を出力する方法だからです。
  2. printfやその他のCRT関数は、cdecl呼び出し規約(呼び出し元スタックのクリーンアップ)を使用しているため、呼び出した後にスタックをクリーンアップする必要があります。厳密に言えば、_exitの後でそれを行う必要がありますが、それは二度と戻らないため、それほど重要ではありません。
  3. CRT関数を使用するには、CRTを初期化する必要があります。あなたはそれがファイルでどのように行われたかを確認することができますVC\crt\src\crt0.c

これが私のために働いた最小限のファイルです(私はVS2008を持っていて、DLLで動作させるためにマニフェストをいじりたくなかったので、静的ライブラリを使用しました)。

.386
.MODEL FLAT
.STACK 4096
.data
  msg db "Hello World!",0
.code
INCLUDELIB LIBCMT
EXTRN _printf:NEAR
EXTRN _exit:NEAR
EXTRN __heap_init:NEAR
EXTRN __mtinit:NEAR
EXTRN __ioinit:NEAR
PUBLIC _main
_main PROC
  push 1
  call __heap_init
  add esp, 4
  push 1
  call __mtinit
  add esp, 4
  call __ioinit
  mov eax, offset msg
  push eax
  call _printf
  pop ecx
  mov eax,0
  push eax
  call _exit
_main ENDP
END _main

MSVCRTの場合、初期化は異なります。たとえば、set_app_typeを呼び出す必要があります。

CRTに依存しないようにするには、OSAPIを使用する必要があります。Win32の場合、WriteFile(ファイルハンドルにGetStdHandle(STD_OUTPUT_HANDLE)を使用)などのWin32関数になります。ここでいくつかの例を参照してください。

于 2010-10-14T10:03:25.803 に答える