web-dev-qa-db-ja.com

Windowsアセンブリでnasmを使用するHello World

nasm を使用して、次のアセンブリをコンパイルしています。ただし、コードはWindowsのコンソールでクラッシュします。

C:\> nasm -f win32 test.asm -o test.o

C:\> ld test.o -o test.exe

section .data
  msg   db    'Hello world!', 0AH
  len   equ   $-msg

section .text
  global _WinMain@16

_WinMain@16:
  mov   edx, len
  mov   ecx, msg
  mov   ebx, 1
  mov   eax, 4
  int   80h

  mov   ebx, 0
  mov   eax, 1
  int   80h

これによると 投稿main関数はWindowsでは使用できません。WinMainに置き換える必要があります。

したがって、エントリポイントが_startまたはmainの場合は、_WinMain@16に変更し、手順の最後のretret 16に変更する必要があります:

私の作業例:

section .text       
 global _WinMain@16       

_WinMain@16:       
 mov eax, 0       
 ret 16 
13
fulvio

最大の問題は、WindowsでLinuxの割り込みを使用しようとしていることです。 int 80はWindowsでは機能しません。

アセンブリを使用しているため、エントリポイントは任意のラベルにすることができます。 ldが検索する標準のエントリポイントは_startです。別のラベルを使用する場合は、-eオプションを使用してldに通知する必要があります。したがって、開始ラベルをメインにしたい場合は、

global main
ld -e main test.o -o test.exe

WindowsでNASMを使用する場合は、リンカーとしてGoLinkを使用することをお勧めします。シンプルなWindowsコンソールアプリを次に示します。

STD_OUTPUT_HANDLE   equ -11
NULL                equ 0

global GobleyGook
extern ExitProcess, GetStdHandle, WriteConsoleA

section .data
msg                 db "Hello World!", 13, 10, 0
msg.len             equ $ - msg

section .bss
dummy               resd 1

section .text
GobleyGook:
    Push    STD_OUTPUT_HANDLE
    call    GetStdHandle

    Push    NULL
    Push    dummy
    Push    msg.len
    Push    msg
    Push    eax
    call    WriteConsoleA 

    Push    NULL
    call    ExitProcess

makefile:

hello: hello.obj
    GoLink.exe  /console /entry GobleyGook hello.obj kernel32.dll  

hello.obj: hello.asm
    nasm -f win32 hello.asm -o hello.obj
30
Gunner

ただし、この同じプログラムはおそらくLinux上のWINEで魅力的に実行されます。 :)

WINEは、Windows PEバイナリ内からのLinuxシステムコールの使用を妨げません。機械語命令はネイティブに実行され、WINEはDLL関数のみを提供します。

8
johnfound