私はアセンブラの専門家ではなく、このトピックに関する知識はかなり浅いですが、値を返すだけの単純な関数呼び出しでMicrosoftVC++コンパイラが何をするのか興味がありました。
次の関数を使用しましょう。
unsigned long __stdcall someFunction ( void * args) {
return 0;
}
これで、__stdcall
呼び出し規約ではCALLEEがスタックの巻き戻しを担当し__cdecl
、関数のCALLERでこれを処理することがわかりました。しかし、この例では、前者に固執したいと思います。
最適化されていないデバッグビルドでは、次の出力が生成されていることがわかりました。
unsigned long __stdcall someFunction (void * args) {
00A31730 push ebp
00A31731 mov ebp,esp
00A31733 sub esp,0C0h
00A31739 push ebx
00A3173A push esi
00A3173B push edi
00A3173C lea edi,[ebp-0C0h]
00A31742 mov ecx,30h
00A31747 mov eax,0CCCCCCCCh
00A3174C rep stos dword ptr es:[edi]
return 0;
00A3174E xor eax,eax
}
00A31750 pop edi
00A31751 pop esi
00A31752 pop ebx
00A31753 mov esp,ebp
00A31755 pop ebp
00A31756 ret 4
可能であれば、このコードスニペットについて説明してくれた人に感謝します。xor
このステートメントが実際にレジスタをリセットしeax
てゼロの戻り値を生成することを私は知っています。また、それret 4
は私には自明です。edi
、、esi
およびebx
レジスターは、元の状態を保存するために前にプッシュされ、後にポップされるので、関数がそれらを自由に使用できるようになっていると思います。しかし、残りの部分については、私には手がかりがありません。
どんな答えでも大歓迎です!:)
ありがとう!