インライン・アセンブラからの C++ 関数呼び出し

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

static long __stdcall a(long* v1, long v2)
{
	*v1 = 100;
	cout << "  関数 a: " << v2 << endl;
	return 0L;
}

static long __stdcall b(long* v1, long v2)
{
	*v1 = 200;
	cout << "  関数 b: " << v2 << endl;
	return 1L;
}

typedef long (__stdcall *func)(long*, long);

int main(int argc, char* argv[])
{
	if (2 != argc){
		cerr << "usage: " << argv[0] << " disp_id" << endl;
		getchar();
		return EXIT_FAILURE;
	}
	// 第 1 引数の数字文字列を数値に変換
	long disp_id = ::strtol(argv[1], NULL, 10);
	if (0L > disp_id || 1L < disp_id){
		cerr << "disp_id: 0 or 1" << endl;
		getchar();
		return EXIT_FAILURE;
	}
	cout << " disp_id: " << disp_id << endl;
	// 関数テーブルを作成
	func p[2];
	func* ref_p = p;
	p[0] = a;
	p[1] = b;
	long out_arg, val;
	__asm{
		; val = p[disp_id](&out, 256L)
		; スタック・フレームの確保
		sub		esp, 8h
		; 引数をスタックに積む
		push	256
		lea		eax, dword ptr out_arg
		push	eax
		; 関数呼び出し
		mov		ecx, ref_p
		mov		eax, disp_id
		shl		eax, 2
		add		eax, ecx
		call	[eax]
		; 返り値の代入
		mov		val, eax
	}
	cout << "  返り値: " << val << endl;
	cout << "出力引数: " << out_arg << endl;
	getchar();

	return EXIT_SUCCESS;
}

BACK


View My Stats