C#でアセンブラを使う方法

MSILのことじゃないよ。MASMアセンブルするx86アセンブラ
手元の環境はMicrosoft Visual C# 2010 Express。
以下、使うための手順。

MASM32 SDKSDKか、Visual C++をインストールして、
ml.exe(アセンブルする)とlink.exe(DLLを作る)をゲット。
それらと同じフォルダに次のバッチファイルを置く。

rem ファイル名:build_dlls.bat
for %%A in ("%~d1%~p1*.asm") do call "%~d0%~p0build_dll.bat" "%%A"
rem ファイル名:build_dll.bat
rem /Sa /Fl"%~n1.lst" はマクロ展開後のコードを知るためのもので、必要ではない
"%~d0%~p0ml.exe" /c /coff /Sa /Fl"%~n1.lst" /Fo"%~n1.obj" %1
"%~d0%~p0link.exe" /dll /out:"%~n1.dll" "%~n1.obj"

次にC#側の設定。
プロジェクト->プロパティ->ビルド イベント->ビルド前に実行するコマンド ライン
と辿り、次のコマンドを入力する(上のbuild_dlls.batをフルパスで指定)。

call "C:\masm32\bin\build_dlls.bat" "$(ProjectDir)"

あとはプロジェクトに拡張子asmのファイルを追加するだけだが、
普通にIDEからファイルを作るとBOM付きのUTF-8になってしまい、MASMで読めない。
そこで、プロジェクトフォルダ(Form1.csとかがある場所)に手動でファイルを作り、
それをプロジェクトに追加する(複数可)。
test.asmというファイルを追加したとして、例えば次のようなコードを書く。

.686
.model flat, stdcall
.code

DLLMain proc hinstDLL:dword, fdwReason:dword, lpvReserved:dword
	mov eax, 1
	ret
DLLMain endp

int_sub proc export a1:dword, a2:dword
	mov eax, a1
	sub eax, a2
	ret
int_sub endp

end DLLMain

これでビルドすれば(単なるデバッグ実行でも)DLLができる。
「ビルド前に実行するコマンド ライン」で、
C#の生成する実行ファイルの場所がカレントディレクトリになるので都合がいい。

このint_subという関数は、引き算をした結果を返すもの。
普通にフォームアプリケーションを新規作成してForm1.csがあるとして、
DLLを呼び出すには、そこへ次のように書く。
実行すれば、13-8の答えがメッセージボックスで表示される。

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("test.dll")]
        extern static int int_sub(int a1, int a2);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            MessageBox.Show(int_sub(13, 8).ToString());
        }
    }
}