6

私はcppプロジェクトに取り組んでいます。プロジェクトを 64 ビットに移行する必要があります。x64 でコンパイルできないインライン アセンブリ コードが含まれています。これは、アセンブリ コードを含む関数です。

void ExternalFunctionCall::callFunction(ArgType resultType, void* resultBuffer)
{
#if defined(_NT_) || defined(__OS2__)

    // I386

    // just copy the args buffer to the stack (it's already layed out correctly)
    int* begin = m_argsBegin;
    int* ptr = m_argsEnd;
    int arr[1000], i=0;
    while (ptr > begin) {
        int val = *(--ptr);

        __asm push val
    }

    void* functionAddress = m_functionAddress;

    // call the function & handle the return value.  use __stdcall calling convention
    switch (resultType) {
    case voidType:
        __asm {
            call functionAddress
        }
        break;
    case pointerType:
    case int32Type:
        __asm {
            call functionAddress
            mov ebx, resultBuffer
            mov dword ptr [ebx],eax
        }
        break;
    case floatType:
        __asm {
            call functionAddress
            mov ebx, resultBuffer
            fstp dword ptr [ebx]
        }
        break;
    case doubleType:
        __asm {
            call functionAddress
            mov ebx, resultBuffer
            fstp qword ptr [ebx]
        }
        break;
    }

スタック、アレイを使用してこの「asm push val」を移行しましたが、機能しませんでした。ただし、コンパイルエラーはスローされませんが、ロジックは機能しませんでした。

それで、「__asm push val」の代わりに C++ で何を使用できるかを尋ねたいと思います。どんな助けでも大歓迎です。

4

3 に答える 3

0

これはやや古い質問だと思いますが、偶然見つけたのはxbyakです。

おそらくあなたが探しているものは何ですか?

于 2014-01-11T13:27:14.603 に答える
0

解決しなければならないことがいくつかあります。(別の質問でコードを調べました)。私が理解したように、このコードは指定されたアドレスにあるかなり抽象的な関数を呼び出すためのラッパーであり、スタック内の一定量のデータを期待し、ArgType に基づいてさまざまなものを返すことができます。

プレーン C でラップしたい場合は、(戻り値に基づいて) いくつかの関数プロトタイプを定義してスイッチで使用する必要がありますが、別の問題を解決する必要があります。これはよりトリッキーです。

このようなものを C に移植する際の問題は、スタックにプッシュしなければならない引数の量 (データ サイズ) が事前にわからないため、プロトタイプの定義に問題が生じることです。

func(char c) が確実にスタック 1 バイトをプッシュするとします (ただし、データの配置のために常に正しいとは限りません)。あなたの場合、データのサイズと同じサイズのパラメーターのセットを持つソリューションについて考える必要があります。スタック上にいる必要があります。これは一見、すぐにできることではありません。

アップデート。func( char [] param ); でそれを行うことができます。ただし、上記の回答で説明した問題もあります。

于 2013-04-22T10:13:31.770 に答える