LoginSignup
26
20

More than 5 years have passed since last update.

WindowsでNASMを使ってアセンブラを動かしてみる

Posted at

Windows環境下でアセンブラを動かしてみたくて,NASMを使ってみたのでメモ

結論

$ nasm -fwin32 hello_world.asm
$ link hello_world.obj /ENTRY:main /SUBSYSTEM:CONSOLE /defaultlib:kernel32.lib

で行けました.

環境

  • OS
    • Windows7 32bit
  • アセンブラ
    • NASM
  • リンカ
    • VisualStudio 付属のlink.exe

を使います.

NASM

こちらからダウンロード
http://www.nasm.us/

(本記事作成時の最新安定版のリンクはこちら
http://www.nasm.us/pub/nasm/releasebuilds/2.11.08/win32/nasm-2.11.08-win32.zip )

zipアーカイブ内のnasm.exeがnasm本体ですので,コンパイル等は必要なくそのまま使えます.

リンカ

Visual Studio2015付属のlink.exeを用いました.

スタートメニュー内のVisual Studio 2015 > Visual Studio Tools > 開発者用コマンドプロンプト for VS2015を用いると,元々PATHが追加されているので楽ちんです.linkと打つだけで実行出来ます.

自分でPATHを追加しても構いません.その場合は,開発者用コマンドプロンプトでwhere linkを実行すると,link.exeの置いてある場所が表示されるのでそれを参考にしてください.

動かすアセンブラ

Hello, World を表示するだけの簡単なアセンブラです.
アセンブラの説明は本記事から外れるので省きます.

今回,printf等のライブラリ関数を使いたくない理由があったので,WriteFileを用いて標準出力へ出力しています.

hello_world.asm
  global _main

  extern  _GetStdHandle@4
  extern  _WriteFile@20
  extern  _ExitProcess@4


  section .text

_main:
  ; DWORD bytes;
  ;  <- prepare local variable
  mov     ebp,  esp
  sub     esp,  4

  ; hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
  ;       (STD_OUTPUT_HANDLE = -11)
  push    -11
  call    _GetStdHandle@4
  mov     ebx, eax

  ; WriteFile( hStdOut, msg, length(msg), &size, 0)
  push    0
  lea     eax, [ebp - 4]
  push    eax
  push    (message_end - message)
  push    message
  push    ebx
  call    _WriteFile@20

  ; ExitProcess(0)
  push    0
  call    _ExitProcess@4

  ; never here
  hlt

message:
  db      'Hello, World', 10
message_end:

(本アセンブラの参考元 : http://stackoverflow.com/questions/1023593/how-to-write-hello-world-in-assembler-under-windows/1029093#1029093 )

実行形式を作成する

2つのステップを踏みます.

  1. アセンブラをCOFF形式のオブジェクトファイルに変換
  2. オブジェクトファイルをリンカで実行形式に

アセンブラをCOFF形式のオブジェクトファイルに変換

今回はWindows 32bit版のものを作りますので,-fオプションでwin32を指定します.

$ nasm -fwin32 hello_world.asm

上記コマンドでCOFF型式のオブジェクトファイルであるhello_world.objが生成されます.

オブジェクトファイルをリンカで実行形式に

$ link hello_world.obj /ENTRY:main /SUBSYSTEM:CONSOLE /defaultlib:kernel32.lib

  • /ENTRYでエントリポイントの指定します(今回はmain
  • /SUBSYSTEMで「Win32 文字モード アプリケーション」であることをリンカに伝えます.
  • /defaultlibGetStdHandle等を呼び出すためのライブラリを指定します.

これでhello_world.exeが生成されたはずです.
あとは実行しましょう.

Hello, World!!!

26
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
20