2012-07-08 7 views
5

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

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

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

    asmfunc(); 

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

    return 0; 
} 
+2

[documentation](http://msdn.microsoft.com/it-it/library/h5w10wxs.aspx)で指定されているように、プロローグ/エピローグコードを記述する必要があります。 [この質問](http://stackoverflow.com/questions/3021513/could-someone-explain-declspecnaked-please)を参照してください。また、実際に 'naked'関数が必要なのかどうかを考えてみましょう。もしあなたが望むのは、組み込みアセンブリを書くだけで、普通の関数を使い、コンパイラにC++の呼び出し規約を扱わせることです。 –

+2

呼び出し規約に注意してください。ネイキッド関数は必要なレジスタを保持しません。 – Mysticial

答えて

12

ネイキッド関数には、コンパイラが生成したプロローグとエピローグコードは含まれません。これは、関数の最後に暗黙のreturn文にも適用されます。

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

基本的には、元の実装asmfuncは、プログラムコードの途中のラベルのように機能します。あなたがあなたの関数を呼び出すときには、本質的にgoto asmfuncを実行しています。すなわち、返すことなく、どこかでコントロールを転送します。

このため、最小限の裸の機能は裸の関数にret指示を置くことはあなたの責任である

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

ようになります。

関連する問題