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!!!