概要
Visual C++で64bitプログラムを開発するときインラインアセンブラが使えないのが問題です。
ここでは、C++側からアセンブラを呼び出す方法を示す。
win64asm.cppがC++のソースファイルで、_tmain関数からアセンブラで記述されたファイルtestsub.asmのtestsub_asm関数を呼び出します。
testsub_asmは2つの引数の32bit整数値の引き算を行い結果を返します。
コマンドプロンプトで動作するプログラムですので、コマンドプロンプト上で実行してください。
テスト環境
コンパイラ
Visual C++ 2013 Express 64bit
アセンブラは上記に含まれるml64.exeを使用
実行環境
Windows 7 Enterprise Service Pack 1 64bit(Sandy Bridge-E)
C++側のソースコード(win64asm.cpp)
C++では、C++上のソースで同じ関数名で引数の違いを認めているので(オーバーライト)実際の関数名は、ソースコードの関数名の後ろに引数の種類を示す文字列がコンパイラで付加されます。
アセンブラの関数は、呼び出し側のC++側で関数名が勝手に修飾され、C++からの呼び出しができなくなるのを防ぐため、extern "C" { }を付加してプロトタイプ宣言を行います。
あとは普通にアセンブラの関数を呼び出しているだけです。
// C++からアセンブラの関数を呼び出すテストサンプル(64bit用)
// testsub_asmの内部は、testsub.asmファイルでコーディングしている
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
extern "C" {
DWORD32 testsub_asm(DWORD32 dtc, DWORD32 src);
}
void _tmain(void){
DWORD32 dtc = 20;
DWORD32 src = 12;
DWORD32 t = testsub_asm(dtc, src);
_tprintf_s( _TEXT("%d\n"), t);
}
アセンブラ側のソースコード(testsub.asm)
.codeは、プログラムコードであることを宣言しています。
public 関数名 は関数が本ファイル以外でも参照できるように宣言しています。
関数名 PROCは関数を開始すること、関数名 ENDPは関数が終わることを宣言しています。 ENDはアセンブラの記述が終了したことを示します。END以降に空行が必要です。
C++から呼び出されるときの第1引数がecx、第2引数がedxに格納されます。
戻り値は、eaxに渡します。
アセンブラのソースをプロジェクトに加えてもアセンブル作業が定義されていません。
アセンブラのソースをプロジェクトに加え、ソリューションエクスプローラで追加したアセンブラのソースファイルのプロパティを表示させます。
構成のプロパティにカスタムビルドツールの全般を選び、以下のように設定します。
カスタムビルドツールが表示されない場合、項目の種類よりカスタムビルドツールを選択し適用を押すとカスタムビルドツールが現れます。
コマンドラインの/cはアセンブルのみでリンク処理をしないことを意味します。
.code
public testsub_asm
testsub_asm PROC
sub ecx,edx
mov eax,ecx
ret
testsub_asm ENDP
END
実行ファイルとソースファイルのダウンロード