アセンブラでWin32APIを使ってみる(MessageBox編)
RubyやPython、JavaScriptのような高級なプログラミング言語が浸透してだいぶ経ちました。
たくさんの便利なライブラリが整っていますし、少ないコード量で面倒な処理ができるところが魅力的です。
とはいえ、こういった言語ばかり触っていると低水準な言語でゴリゴリと書きたくなってきませんか?ほら、なってきましたね。
そんなわけで、もっとも低水準なプログラミング環境といえるであろうアセンブラでWin32APIを使ったアプリケーションを作ります。
今回使うツールは以下の通り。
ちなみに最初はMASMを使おうと思ったのですが、Microsoft純正だけありWin32APIのサポートがしっかりされていてつまらないので、今回はNASMを使って縛りプレイをしてみます。
ALINKは。
上記のALINKのサイトの
NASM、ALINK、win32.libは同じフォルダに入れてソースコードと同じフォルダに置きます。
まずはお決まりのHello worldを作ってみます。
ウィンドウ表示をすると複雑になるので、MessageBox関数で表示させることにします。
以下のようなプログラムを test.asm などのファイル名で保存します。
プログラム中で呼び出しているAPIは、あらかじめ extern ~ で関数名を指定しておく必要があります。
(たまに win32.lib に定義が含まれていないAPI関数もあるので注意。)
アセンブラからAPIを呼び出すにはcall命令を使います。
関数の引数はpush命令でスタックに積みます。面倒ですね。
また、C/C++の場合は windows.h で関数形式マクロとして「MessageBox」が用意されていましたが、アセンブリ言語で呼び出す場合は使えません。
(「MessageBox」は Shift-JIS版API の「MessageBoxA」と Unicode版API の「MessageBoxW」を、プログラム上の文字コード設定に合わせて切り替えるマクロです。)
アセンブリ言語から呼び出す場合は「MessageBoxA」のように直接関数名を指定する必要があります。
プログラムの最後には必ず ExitProcess 関数を呼び出します。
これを呼び出し忘れると、メッセージボックスを閉じてもプロセスが終了しません。
作ったプログラムがタスクマネージャ上に残りつづける事態になるので注意しましょう。
このソースコードから実行ファイル (.exe) を生成してみましょう。
NASM で test.obj を生成
ALINK で test.obj と win32.lib をリンクしてexeファイルを生成
アセンブリ言語を書いているとコンパイラの恩恵を感じますね。
もし次回があれば、ウィンドウ表示をしてみるつもりです。
たくさんの便利なライブラリが整っていますし、少ないコード量で面倒な処理ができるところが魅力的です。
とはいえ、こういった言語ばかり触っていると低水準な言語でゴリゴリと書きたくなってきませんか?ほら、なってきましたね。
そんなわけで、もっとも低水準なプログラミング環境といえるであろうアセンブラでWin32APIを使ったアプリケーションを作ります。
今回使うツールは以下の通り。
- NASM (アセンブラ) - http://sourceforge.net/projects/nasm/
- ALINK (リンカ) - http://alink.sourceforge.net/download.html
ちなみに最初はMASMを使おうと思ったのですが、Microsoft純正だけありWin32APIのサポートがしっかりされていてつまらないので、今回はNASMを使って縛りプレイをしてみます。
上記のALINKのサイトの
「Download my Win32 Import library(win32.lib)」からALINK用のWin32APIライブラリをダウンロードしておきます。
NASM、ALINK、win32.libは同じフォルダに入れてソースコードと同じフォルダに置きます。
まずはお決まりのHello worldを作ってみます。
ウィンドウ表示をすると複雑になるので、MessageBox関数で表示させることにします。
以下のようなプログラムを test.asm などのファイル名で保存します。
bits 32 extern MessageBoxA extern ExitProcess section .text global winmain winmain: push dword 0 push dword title push dword string push dword 0 call MessageBoxA push dword 0 call ExitProcess ret section .data title: db 'Test', 0 string: db 'Hello world!', 0
(たまに win32.lib に定義が含まれていないAPI関数もあるので注意。)
アセンブラからAPIを呼び出すにはcall命令を使います。
関数の引数はpush命令でスタックに積みます。面倒ですね。
また、C/C++の場合は windows.h で関数形式マクロとして「MessageBox」が用意されていましたが、アセンブリ言語で呼び出す場合は使えません。
(「MessageBox」は Shift-JIS版API の「MessageBoxA」と Unicode版API の「MessageBoxW」を、プログラム上の文字コード設定に合わせて切り替えるマクロです。)
アセンブリ言語から呼び出す場合は「MessageBoxA」のように直接関数名を指定する必要があります。
プログラムの最後には必ず ExitProcess 関数を呼び出します。
これを呼び出し忘れると、メッセージボックスを閉じてもプロセスが終了しません。
作ったプログラムがタスクマネージャ上に残りつづける事態になるので注意しましょう。
このソースコードから実行ファイル (.exe) を生成してみましょう。
NASM で test.obj を生成
nasm.exe test.asm -fwin32
ALINK で test.obj と win32.lib をリンクしてexeファイルを生成
alink.exe test.obj win32.lib -oPE -entry winmain
アセンブリ言語を書いているとコンパイラの恩恵を感じますね。
もし次回があれば、ウィンドウ表示をしてみるつもりです。
コメント
コメントを投稿