6

私は ASM を学ぼうとしており、C++ と組み合わせていくつかのことを試してみたいと思っています。ASM 部分はネイキッド関数で実行されます。しかし、関数 (空) を呼び出すたびに、次の関数でアプリケーションがクラッシュします。ネイキッド関数を機能させるにはどうすればよいですか? esp などをポップする必要がありますか? 例が役立つ場合があります。

_declspec(naked) void asmfunc()
{
    _asm
    {
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    i = 1;

    asmfunc();

    cout << i << endl; // <-- crash
    system("pause");

    return 0;
}
4

2 に答える 2

15

ネイキッド関数には、コンパイラによって生成されたプロローグおよびエピローグ コードは含まれません。これは、関数の最後の暗黙の return ステートメントにも当てはまります。

これは、宣言した関数retの最後に命令がないことを意味します。コントロールが に転送されるとasmfunc、元に戻ることはありません。関数は、クラッシュする何かにぶつかるまで、その場所に存在するコードを実行し続けます。

基本的に、元の の実装はasmfunc、プログラム コードの途中でラベルとして機能します。そして、あなたが関数を呼び出すとき、あなたは本質的に を行っていますgoto asmfunc。つまり、戻りの希望なしにどこかに制御を移します。

このため、最小限のネイキッド関数は次のようになります。

_declspec(naked) void asmfunc()
{
    _asm
    {
      ret
    }
}

retネイキッド関数に命令を配置するのは、ユーザーの責任です。

于 2012-07-08T18:09:46.357 に答える
1

C言語プログラムのネイキッド関数には、タスクを実行する関数を準備するプロローグとエピローグのコードが含まれていません。プロローグとエピローグのコードを作成するのはあなたの仕事です。次のコードでは、プロローグとエピローグを定義していることがわかります。そこでアセンブリ コードを定義できます。

__declspec(naked) void NakedFunction() {
    __asm {
        push ebp
        mov ebp, esp
    }

    __asm {
        // write your code here
    }

    __asm {
        leave
        ret
    }
}

int main() {
    NakedFunction();

    return 0x0;
}
于 2018-05-28T07:16:05.953 に答える