2012年2月21日火曜日

ジャンプ!!!

先日のじっけ~~~ん記事で
deleteで例外は発生するかの実験コードを書きました。

http://developerwaiwai.blogspot.com/2012/02/blog-post_16.html

例外といえば、try-catch!!!
そもそもtry-catchってどうコンパイルされるのだろう???
longjumpってのは聞いたことあるけど・・・

ってことで、コンパイル結果のアセンブラを見てみました^^
長いので肝心な部分だけを掲載。


80488c3: 8b 45 e4 mov eax,DWORD PTR [ebp-28]
80488c6: 89 04 24 mov DWORD PTR [esp],eax
80488c9: e8 a2 00 00 00 call 8048970 <A::~A()>
80488ce: 8b 45 e4 mov eax,DWORD PTR [ebp-28]
80488d1: 89 04 24 mov DWORD PTR [esp],eax
80488d4: e8 93 fd ff ff call 804866c <operator delete(void*)@plt>
80488d9: eb 52 jmp 804892d <main+0x97>
80488db: 89 45 e0 mov DWORD PTR [ebp-32],eax
80488de: 8b 45 e0 mov eax,DWORD PTR [ebp-32]
80488e1: 89 04 24 mov DWORD PTR [esp],eax
80488e4: e8 33 fe ff ff call 804871c <__cxa_begin_catch@plt>
80488e9: c7 44 24 04 64 8a 04 mov DWORD PTR [esp+4],0x8048a64
80488f0: 08
80488f1: c7 04 24 10 9d 04 08 mov DWORD PTR [esp],0x8049d10
80488f8: e8 af fd ff ff call 80486ac <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>
80488fd: c7 44 24 04 0c 87 04 mov DWORD PTR [esp+4],0x804870c
8048904: 08
8048905: 89 04 24 mov DWORD PTR [esp],eax
8048908: e8 df fd ff ff call 80486ec <std::ostream::operator<<(std::ostream& (*)(std::ostream&))@plt>
804890d: e8 ea fd ff ff call 80486fc <__cxa_end_catch@plt>



フムフム。
deleteの結果、デストラクタ~A()がコールされて、
operator deleteがコール・・・
なるほどなるほど。

で、次は・・・・
え!!!
main終了ポイントまで「jmp」になってる!!!
普通に考えると、このアセンブラでは絶対にcatchのコードが
実行されません。。。

どうやら、例外が発生すると、直接catchコードにジャンプしている
ようです!!!
なるほどなぁ!!!

面白いですね!!!


あ、x86系のアセンブラなのであしからず^^