3

基本的に、私は次のようなことができるようにしたいと思います。

//assume myFunction is defined and takes one argument that is an int
char * functionName = "myFunction";
int arg = 5;

__asm{
    push a
    call functionName
}

基本的には、名前が文字列に格納されている関数を呼び出したいと思います。これを行うための適切な構文は何でしょうか?

編集:x86アセンブリについて話している

4

3 に答える 3

1

少なくとも直接はできません。

callはパラメータとしてアドレスを取ります。「callfunctionName」と記述しても、リンカはfunctionnameを関数の実際のアドレスに置き換えます。最初にその文字列をそのアドレスにマップする必要があります。一般に、CおよびC ++は、これを可能にする関数名マッピングに関するランタイムメタデータをサポートしていません。関数がDLLからエクスポートされる場合は、GetProcAddressを使用してそのアドレスを見つけることができます。

関数のリストが静的である場合は、事前に自分でマッピングを作成できます。

何かのようなもの:

std:map<string, PVOID> functionMappings;
functionMappings["MyFunction"] = MyFunction;


// Later


PVOID function = functionMappings["MyFunction"];

__asm
{
    push a;
    call [function]
}

いくつかのメモ:

標準では、関数ポインタはPVOIDよりも大きい可能性があるとされていると思います。これは、Windows x86/x64プラットフォームで機能するはずです。

使用している呼び出し規約については言及していません。このコードはstdcallを前提としています。

これは、達成したい非常に奇妙なことです。どのような問題を解決しようとしていますか?

于 2010-02-18T18:25:05.177 に答える
1

これは不可能です。名前による呼び出し操作を実行しようとしています。アセンブラには、値がアドレスである値による呼び出しのみがあります。名前をアドレスに変換し、そのアドレスをアセンブラに渡す必要があります。つまり、名前とアドレスの間に何らかの相互参照が必要です。コンパイラーはここで役に立ちます。CおよびC++では、関数ポインターを検索して、アセンブラーに渡すことができる関数のアドレスを取得するために必要な構文を確認する必要があります。

プリエンプティブ:はい、コンパイラーが実行可能ファイルにシンボルを埋め込んで検索できる場合もありますが、それは問題に満ちた方法です。データの形式はコンパイラのバージョン間で変わる可能性があり、情報はリンカによって削除される可能性があります。

于 2010-02-18T18:25:23.320 に答える
0

これを簡単に行う方法がわかりません。一部の高級言語では、リフレクションを使用してこれを実現できますが、Cもアセンブリもその機能を利用できません。リンカが完了するまでに、すべての関数呼び出しはアドレスに解決されます。デバッグインフラストラクチャにアクセスできる場合は、関数名を逆引きしてアドレスを取得できますが、アセンブリから取得するのは簡単なことではありません。

または、コンパイル時に定義された関数ポインターを使用して、関心のある関数のアドレスを格納することもできます(ただし、おそらく文字列比較テーブルルックアップを介して、文字列を関数ポインターに変換する方法が必要です)。これに興味がある場合は、同等のCを記述してから、コンパイラが出力するアセンブリコードを調べて、関数ポインタがどのように処理されるかを確認することをお勧めします。

于 2010-02-18T18:30:14.367 に答える