4.__declspec(naked)生成純アセンブリ使用方法


__declspec(naked)は、コンパイラ関数コードを教えるためのアセンブリ言語であり、コンパイラがアセンブリコードを追加する必要はなく、一般的には純粋なアセンブリを生成することができる.
MSDNはnakedキーワードを検索すればよい:
For functions declared with the naked attribute, the compiler generates code without prolog and epilog code. You can use this feature to write your own prolog/epilog code sequences using inline assembler code. Naked functions are particularly useful in writing virtual device drivers. Note that the naked attribute is only valid on x86, and is not available on x64 or Itanium.
例:
#define  NAKED __declspec(naked) 
VOID NAKED MyFunc() 
{ 
	__asm 
	{ 
		ret 
	} 
} 

1.nakedキーワードを使用するには、EBPポインタを自分で構築する必要があります(使用した場合).
2.VOIDを使用しない限り、RETまたはRET n命令を自分で使用して返さなければならない.
これはコンパイラが直接持ってきたアセンブリ関数コードなので、最初にコンテキストフラグビット(スタックを押す)を保存し、最後にコンテキストを復元する(スタックを出る)ことを覚えておく必要があります.そして最後にretコマンドを追加します.
一般的なアセンブリ埋め込みコードでは、コンテキストを保存する必要はありません.保存しても大丈夫ですが、retコマンドを追加することはできません.コンパイラも1つ追加するので、retコマンドは同時に2回実行できません.境界を越えたエラーを引き起こす.
次のコードがあります.
C呼び出し:
#define  NAKED __declspec(naked) 
int NAKED Add(int a,int b) 
{ 
	__asm 
	{ 
		mov eax, a
		add eax, b
		ret
	} 
} 

int _tmain(int argc, _TCHAR* argv[])
{
	Add(1,2);
	return 0;
}
このとき呼び出しアセンブリは次のとおりです.
	Add(1,2);
00A217EE  push        2    
00A217F0  push        1    
00A217F2  call        Add (0A21087h) 
00A217F7  add         esp,8 // C ,  
	return 0;
__stdcall呼び出し:
#define  NAKED __declspec(naked) 
int NAKED __stdcall Add(int a,int b) 
{ 
	__asm 
	{ 
		mov eax, a
		add eax, b
		ret 8 // 
	} 
} 

int _tmain(int argc, _TCHAR* argv[])
{
	Add(1,2);
	return 0;
}
このとき呼び出しアセンブリは次のとおりです.
	Add(1,2);
00D117EE  push        2    
00D117F0  push        1    
00D117F2  call        Add (0D111D1h) 
	return 0;
デバッグが細心の注意を払うと、前のAddの戻り結果が間違っていることに気づくはずです.
そのdebugアセンブリは次のとおりです.
0:000:x86> u 01381380 
test1!Add [f:\test1\test1\test1.cpp @ 9]:
01381380 8b4508          mov     eax,dword ptr [ebp+8]
01381383 03450c          add     eax,dword ptr [ebp+0Ch]
01381386 c20800          ret     8
は、[ebp+8]および[ebp+c]がそれぞれaおよびbを表し、
ebpはここではespの値であるはずなので、
#define  NAKED __declspec(naked) 
int  NAKED __stdcall Add(int a,int b) 
{ 
	__asm 
	{ 
		push ebp
		mov ebp,esp
		mov eax, a
		add eax, b
		leave
		ret 8
	} 
}