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
を用いて標準出力へ出力しています.
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つのステップを踏みます.
- アセンブラをCOFF形式のオブジェクトファイルに変換
- オブジェクトファイルをリンカで実行形式に
アセンブラを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 文字モード アプリケーション」であることをリンカに伝えます. -
/defaultlib
でGetStdHandle
等を呼び出すためのライブラリを指定します.
これでhello_world.exe
が生成されたはずです.
あとは実行しましょう.
Hello, World!!!