アセンブラでWin32APIを使ってみる(MessageBox編)

RubyやPython、JavaScriptのような高級なプログラミング言語が浸透してだいぶ経ちました。
たくさんの便利なライブラリが整っていますし、少ないコード量で面倒な処理ができるところが魅力的です。
とはいえ、こういった言語ばかり触っていると低水準な言語でゴリゴリと書きたくなってきませんか?ほら、なってきましたね。

そんなわけで、もっとも低水準なプログラミング環境といえるであろうアセンブラでWin32APIを使ったアプリケーションを作ります。
今回使うツールは以下の通り。

ちなみに最初はMASMを使おうと思ったのですが、Microsoft純正だけありWin32APIのサポートがしっかりされていてつまらないので、今回はNASMを使って縛りプレイをしてみます。

ALINKは。
上記の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

プログラム中で呼び出している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 を生成
nasm.exe test.asm -fwin32

ALINK で test.obj と win32.lib をリンクしてexeファイルを生成
alink.exe test.obj win32.lib -oPE -entry winmain


アセンブリ言語を書いているとコンパイラの恩恵を感じますね。
もし次回があれば、ウィンドウ表示をしてみるつもりです。

コメント

このブログの人気の投稿

基本波形の生成

(1)C言語で音声合成もどき ~WAVファイルを生成する~

(2)C言語で音声合成もどき ~母音の生成~