程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++編譯器如何實現異常處理(1)

C++編譯器如何實現異常處理(1)

編輯:C++入門知識
譯者注:本文在網上已經有幾個譯本,但都不完整,所以我決定自己把它翻譯過來。雖然力求信、雅、達,但鑒於這是我的第一次翻譯經歷,不足之處敬請諒解並指出。 與傳統語言相比,C++的一項革命性創新就是它支持異常處理。傳統的錯誤處理方式經常滿足不了要求,而異常處理則是一個極好的替代解決方案。它將正常代碼和錯誤處理代碼清楚的劃分開來,程序變得非常干淨並且輕易維護。本文討論了編譯器如何實現異常處理。我將假定你已經熟悉異常處理的語法和機制。本文還提供了一個用於VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個,你只需要調用下面這個函數: install_my_handler(); 之後,程序中的所有異常,從它們被拋出到堆棧展開(stack unwinding),再到調用catch塊,最後到程序恢復正常運行,都將由我的異常處理庫來治理。 與其它C++特性一樣,C++標准並沒有規定編譯器應該如何來實現異常處理。這意味著每一個編譯器的提供商都可以用它們認為恰當的方式來實現它。下面我會描述一下VC++是怎麼做的,但即使你使用其它的編譯器或操作系統①,本文也應該會是一篇很好的學習材料。VC++的實現方式是以windows系統的結構化異常處理(SEH)②為基礎的。
  
  結構化異常處理—概述
  
  在本文的討論中,我認為異常或者是被明確的拋出的,或者是由於除零溢出、空指針訪問等引起的。當它發生時會產生一個中斷,接下來控制權就會傳遞到操作系統的手中。操作系統將調用異常處理程序,檢查從異常發生位置開始的函數調用序列,進行堆棧展開和控制權轉移。Windows定義了結構“EXCEPTION_REGISTRATION”,使我們能夠向操作系統注冊自己的異常處理程序。 strUCt EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWord handler; }; 注冊時,只需要創建這樣一個結構,然後把它的地址放到FS段偏移0的位置上去就行了。下面這句匯編代碼演示了這一操作:mov FS:[0], exc_regp
  
  prev字段用於建立一個EXCEPTION_REGISTRATION結構的鏈表,每次注冊新的EXCEPTION_REGISTRATION時,我們都要把原來注冊的那個的地址存到prev中。那麼,那個異常回調函數長什麼樣呢?在excpt.h中,windows定義了它的原形:
  
  EXCEPTION_DISPOSITION (*handler)( _EXCEPTION_RECORD *ExcRecord, void* EstablisherFrame, _CONTEXT *ContextRecord, void* DispatcherContext); 不要管它的參數和返回值,我們先來看一個簡單的例子。下面的程序注冊了一個異常處理程序,然後通過除以零產生了一個異常。異常處理程序捕捉了它,打印了一條消息就完事大吉並退出了。
  
  #include #include using std::cout; using std::endl; struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; EXCEPTION_DISPOSITION myHandler( _EXCEPTION_RECORD *ExcRecord, void * EstablisherFrame, _CONTEXT *ContextRecord, void * DispatcherContext) { cout << "In the exception handler" << endl; cout << "Just a demo. exiting..." << endl; exit(0); return ExceptionContinueExecution; //不會運行到這 } int g_div = 0; void bar() { //初始化一個EXCEPTION_REGISTRATION結構 EXCEPTION_REGISTRATION reg, *preg = ® reg.handler = (DWORD)myHandler; //取得當前異常處理鏈的“頭” DWORD prev; _asm { mov EAX, FS:[0] mov prev, EAX } reg.prev = (EXCEPTION_REGISTRATION*) prev; //注冊! _asm { mov EAX, preg mov FS:[0], EAX } //產生一個異常 int j = 10 / g_div; //異常,除零溢出 } int main() { bar(); return 0; } /*-------輸出------------------- In the exception handler Just a demo. exiting... ---------------------------------*/ 注重EXCEPTION_REGISTRATION必須定義在棧上,並且必須位於比上一個結點更低的內存地址上,Windows對此有嚴格要求,達不到的話,它就會馬上終止進程。
   譯者注:本文在網上已經有幾個譯本,但都不完整,所以我決定自己把它翻譯過來。雖然力求信、雅、達,但鑒於這是我的第一次翻譯經歷,不足之處敬請諒解並指出。 與傳統語言相比,C++的一項革命性創新就是它支持異常處理。傳統的錯誤處理方式經常滿足不了要求,而異常處理則是一個極好的替代解決方案。它將正常代碼和錯誤處理代碼清楚的劃分開來,程序變得非常干淨並且輕易維護。本文討論了編譯器如何實現異常處理。我將假定你已經熟悉異常處理的語法和機制。本文還提供了一個用於VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個,你只需要調用下面這個函數: install_my_handler(); 之後,程序中的所有異常,從它們被拋出到堆棧展開(stack unwinding),再到調用catch塊,最後到程序恢復正常運行,都將由我的異常處理庫來治理。 與其它C++特性一樣,C++標准並沒有規定編譯器應該如何來實現異常處理。這意味著每一個編譯器的提供商都可以用它們認為恰當的方式來實現它。下面我會描述一下VC++是怎麼做的,但即使你使用其它的編譯器或操作系統①,本文也應該會是一篇很好的學習材料。VC++的實現方式是以windows系統的結構化異常處理(SEH)②為基礎的。
  
  結構化異常處理—概述
  
  在本文的討論中,我認為異常或者是被明確的拋出的,或者是由於除零溢出、空指針訪問等引起的。當它發生時會產生一個中斷,接下來控制權就會傳遞到操作系統的手中。操作系統將調用異常處理程序,檢查從異常發生位置開始的函數調用序列,進行堆棧展開和控制權轉移。Windows定義了結構“EXCEPTION_REGISTRATION”,使我們能夠向操作系統注冊自己的異常處理程序。 struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; 注冊時,只需要創建這樣一個結構,然後把它的地址放到FS段偏移0的位置上去就行了。下面這句匯編代碼演示了這一操作:mov FS:[0], exc_regp
  
  prev字段用於建立一個EXCEPTION_REGISTRATION結構的鏈表,每次注冊新的EXCEPTION_REGISTRATION時,我們都要把原來注冊的那個的地址存到prev中。那麼,那個異常回調函數長什麼樣呢?在excpt.h中,windows定義了它的原形:
  
  EXCEPTION_DISPOSITION (*handler)( _EXCEPTION_RECORD *ExcRecord, void* EstablisherFrame, _CONTEXT *ContextRecord, void* DispatcherContext); 不要管它的參數和返回值,我們先來看一個簡單的例子。下面的程序注冊了一個異常處理程序,然後通過除以零產生了一個異常。異常處理程序捕捉了它,打印了一條消息就完事大吉並退出了。
  
  #include #include using std::cout; using std::endl; struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; EXCEPTION_DISPOSITION myHandler( _EXCEPTION_RECORD *ExcRecord, void * EstablisherFrame, _CONTEXT *ContextRecord, void * DispatcherContext) { cout << "In the exception handler" << endl; cout << "Just a demo. exiting..." << endl; exit(0); return ExceptionContinueExecution; //不會運行到這 } int g_div = 0; void bar() { //初始化一個EXCEPTION_REGISTRATION結構 EXCEPTION_REGISTRATION reg, *preg = ® reg.handler = (DWORD)myHandler; //取得當前異常處理鏈的“頭” DWORD prev; _asm { mov EAX, FS:[0] mov prev, EAX } reg.prev = (EXCEPTION_REGISTRATION*) prev; //注冊! _asm { mov EAX, preg mov FS:[0], EAX } //產生一個異常 int j = 10 / g_div; //異常,除零溢出 } int main() { bar(); return 0; } /*-------輸出------------------- In the exception handler Just a demo. exiting... ---------------------------------*/ 注重EXCEPTION_REGISTRATION必須定義在棧上,並且必須位於比上一個結點更低的內存地址上,Windows對此有嚴格要求,達不到的話,它就會馬上終止進程。 譯者注:本文在網上已經有幾個譯本,但都不完整,所以我決定自己把它翻譯過來。雖然力求信、雅、達,但鑒於這是我的第一次翻譯經歷,不足之處敬請諒解並指出。 與傳統語言相比,C++的一項革命性創新就是它支持異常處理。傳統的錯誤處理方式經常滿足不了要求,而異常處理則是一個極好的替代解決方案。它將正常代碼和錯誤處理代碼清楚的劃分開來,程序變得非常干淨並且輕易維護。本文討論了編譯器如何實現異常處理。我將假定你已經熟悉異常處理的語法和機制。本文還提供了一個用於VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個,你只需要調用下面這個函數: install_my_handler();
   之後,程序中的所有異常,從它們被拋出到堆棧展開(stack unwinding),再到調用catch塊,最後到程序恢復正常運行,都將由我的異常處理庫來治理。 與其它C++特性一樣,C++標准並沒有規定編譯器應該如何來實現異常處理。這意味著每一個編譯器的提供商都可以用它們認為恰當的方式來實現它。下面我會描述一下VC++是怎麼做的,但即使你使用其它的編譯器或操作系統①,本文也應該會是一篇很好的學習材料。VC++的實現方式是以windows系統的結構化異常處理(SEH)②為基礎的。
  
  結構化異常處理—概述
  
  在本文的討論中,我認為異常或者是被明確的拋出的,或者是由於除零溢出、空指針訪問等引起的。當它發生時會產生一個中斷,接下來控制權就會傳遞到操作系統的手中。操作系統將調用異常處理程序,檢查從異常發生位置開始的函數調用序列,進行堆棧展開和控制權轉移。Windows定義了結構“EXCEPTION_REGISTRATION”,使我們能夠向操作系統注冊自己的異常處理程序。 struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; 注冊時,只需要創建這樣一個結構,然後把它的地址放到FS段偏移0的位置上去就行了。下面這句匯編代碼演示了這一操作:mov FS:[0], exc_regp
  
  prev字段用於建立一個EXCEPTION_REGISTRATION結構的鏈表,每次注冊新的EXCEPTION_REGISTRATION時,我們都要把原來注冊的那個的地址存到prev中。那麼,那個異常回調函數長什麼樣呢?在excpt.h中,windows定義了它的原形:
  
  EXCEPTION_DISPOSITION (*handler)( _EXCEPTION_RECORD *ExcRecord, void* EstablisherFrame, _CONTEXT *ContextRecord, void* DispatcherContext); 不要管它的參數和返回值,我們先來看一個簡單的例子。下面的程序注冊了一個異常處理程序,然後通過除以零產生了一個異常。異常處理程序捕捉了它,打印了一條消息就完事大吉並退出了。
  
  #include #include using std::cout; using std::endl; struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; EXCEPTION_DISPOSITION myHandler( _EXCEPTION_RECORD *ExcRecord, void * EstablisherFrame, _CONTEXT *ContextRecord, void * DispatcherContext) { cout << "In the exception handler" << endl; cout << "Just a demo. exiting..." << endl; exit(0); return ExceptionContinueExecution; //不會運行到這 } int g_div = 0; void bar() { //初始化一個EXCEPTION_REGISTRATION結構 EXCEPTION_REGISTRATION reg, *preg = ® reg.handler = (DWORD)myHandler; //取得當前異常處理鏈的“頭” DWORD prev; _asm { mov EAX, FS:[0] mov prev, EAX } reg.prev = (EXCEPTION_REGISTRATION*) prev; //注冊! _asm { mov EAX, preg mov FS:[0], EAX } //產生一個異常 int j = 10 / g_div; //異常,除零溢出 } int main() { bar(); return 0; } /*-------輸出------------------- In the exception handler Just a demo. exiting... ---------------------------------*/ 注重EXCEPTION_REGISTRATION必須定義在棧上,並且必須位於比上一個結點更低的內存地址上,Windows對此有嚴格要求,達不到的話,它就會馬上終止進程。 譯者注:本文在網上已經有幾個譯本,但都不完整,所以我決定自己把它翻譯過來。雖然力求信、雅、達,但鑒於這是我的第一次翻譯經歷,不足之處敬請諒解並指出。 與傳統語言相比,C++的一項革命性創新就是它支持異常處理。傳統的錯誤處理方式經常滿足不了要求,而異常處理則是一個極好的替代解決方案。它將正常代碼和錯誤處理代碼清楚的劃分開來,程序變得非常干淨並且輕易維護。本文討論了編譯器如何實現異常處理。我將假定你已經熟悉異常處理的語法和機制。本文還提供了一個用於VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個,你只需要調用下面這個函數: install_my_handler(); 之後,程序中的所有異常,從它們被拋出到堆棧展開(stack unwinding),再到調用catch塊,最後到程序恢復正常運行,都將由我的異常處理庫來治理。 與其它C++特性一樣,C++標准並沒有規定編譯器應該如何來實現異常處理。這意味著每一個編譯器的提供商都可以用它們認為恰當的方式來實現它。下面我會描述一下VC++是怎麼做的,但即使你使用其它的編譯器或操作系統①,本文也應該會是一篇很好的學習材料。VC++的實現方式是以windows系統的結構化異常處理(SEH)②為基礎的。
  
  結構化異常處理—概述
  
  在本文的討論中,我認為異常或者是被明確的拋出的,或者是由於除零溢出、空指針訪問等引起的。當它發生時會產生一個中斷,接下來控制權就會傳遞到操作系統的手中。操作系統將調用異常處理程序,檢查從異常發生位置開始的函數調用序列,進行堆棧展開和控制權轉移。Windows定義了結構“EXCEPTION_REGISTRATION”,使我們能夠向操作系統注冊自己的異常處理程序。 struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; 注冊時,只需要創建這樣一個結構,然後把它的地址放到FS段偏移0的位置上去就行了。下面這句匯編代碼演示了這一操作:mov FS:[0], exc_regp
  
  prev字段用於建立一個EXCEPTION_REGISTRATION結構的鏈表,每次注冊新的EXCEPTION_REGISTRATION時,我們都要把原來注冊的那個的地址存到prev中。那麼,那個異常回調函數長什麼樣呢?在excpt.h中,windows定義了它的原形:
  
  EXCEPTION_DISPOSITION (*handler)( _EXCEPTION_RECORD *ExcRecord, void* EstablisherFrame, _CONTEXT *ContextRecord, void* DispatcherContext); 不要管它的參數和返回值,我們先來看一個簡單的例子。下面的程序注冊了一個異常處理程序,然後通過除以零產生了一個異常。異常處理程序捕捉了它,打印了一條消息就完事大吉並退出了。
  
  #include #include using std::cout; using std::endl; struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; EXCEPTION_DISPOSITION myHandler( _EXCEPTION_RECORD *ExcRecord, void * EstablisherFrame, _CONTEXT *ContextRecord, void * DispatcherContext) { cout << "In the exception handler" << endl; cout << "Just a demo. exiting..." << endl; exit(0); return ExceptionContinueExecution; //不會運行到這 } int g_div = 0; void bar() { //初始化一個EXCEPTION_REGISTRATION結構 EXCEPTION_REGISTRATION reg, *preg = ® reg.handler = (DWORD)myHandler; //取得當前異常處理鏈的“頭” DWORD prev; _asm { mov EAX, FS:[0] mov prev, EAX } reg.prev = (EXCEPTION_REGISTRATION*) prev; //注冊! _asm { mov EAX, preg mov FS:[0], EAX } //產生一個異常 int j = 10 / g_div; //異常,除零溢出 } int main() { bar(); return 0; } /*-------輸出------------------- In the exception handler Just a demo. exiting... ---------------------------------*/
   注重EXCEPTION_REGISTRATION必須定義在棧上,並且必須位於比上一個結點更低的內存地址上,Windows對此有嚴格要求,達不到的話,它就會馬上終止進程。 譯者注:本文在網上已經有幾個譯本,但都不完整,所以我決定自己把它翻譯過來。雖然力求信、雅、達,但鑒於這是我的第一次翻譯經歷,不足之處敬請諒解並指出。 與傳統語言相比,C++的一項革命性創新就是它支持異常處理。傳統的錯誤處理方式經常滿足不了要求,而異常處理則是一個極好的替代解決方案。它將正常代碼和錯誤處理代碼清楚的劃分開來,程序變得非常干淨並且輕易維護。本文討論了編譯器如何實現異常處理。我將假定你已經熟悉異常處理的語法和機制。本文還提供了一個用於VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個,你只需要調用下面這個函數: install_my_handler(); 之後,程序中的所有異常,從它們被拋出到堆棧展開(stack unwinding),再到調用catch塊,最後到程序恢復正常運行,都將由我的異常處理庫來治理。 與其它C++特性一樣,C++標准並沒有規定編譯器應該如何來實現異常處理。這意味著每一個編譯器的提供商都可以用它們認為恰當的方式來實現它。下面我會描述一下VC++是怎麼做的,但即使你使用其它的編譯器或操作系統①,本文也應該會是一篇很好的學習材料。VC++的實現方式是以windows系統的結構化異常處理(SEH)②為基礎的。
  
  結構化異常處理—概述
  
  在本文的討論中,我認為異常或者是被明確的拋出的,或者是由於除零溢出、空指針訪問等引起的。當它發生時會產生一個中斷,接下來控制權就會傳遞到操作系統的手中。操作系統將調用異常處理程序,檢查從異常發生位置開始的函數調用序列,進行堆棧展開和控制權轉移。Windows定義了結構“EXCEPTION_REGISTRATION”,使我們能夠向操作系統注冊自己的異常處理程序。 struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; 注冊時,只需要創建這樣一個結構,然後把它的地址放到FS段偏移0的位置上去就行了。下面這句匯編代碼演示了這一操作:mov FS:[0], exc_regp
  
  prev字段用於建立一個EXCEPTION_REGISTRATION結構的鏈表,每次注冊新的EXCEPTION_REGISTRATION時,我們都要把原來注冊的那個的地址存到prev中。那麼,那個異常回調函數長什麼樣呢?在excpt.h中,windows定義了它的原形:
  
  EXCEPTION_DISPOSITION (*handler)( _EXCEPTION_RECORD *ExcRecord, void* EstablisherFrame, _CONTEXT *ContextRecord, void* DispatcherContext); 不要管它的參數和返回值,我們先來看一個簡單的例子。下面的程序注冊了一個異常處理程序,然後通過除以零產生了一個異常。異常處理程序捕捉了它,打印了一條消息就完事大吉並退出了。
  
  #include #include using std::cout; using std::endl; struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; EXCEPTION_DISPOSITION myHandler( _EXCEPTION_RECORD *ExcRecord, void * EstablisherFrame, _CONTEXT *ContextRecord, void * DispatcherContext) { cout << "In the exception handler" << endl; cout << "Just a demo. exiting..." << endl; exit(0); return ExceptionContinueExecution; //不會運行到這 } int g_div = 0; void bar() { //初始化一個EXCEPTION_REGISTRATION結構 EXCEPTION_REGISTRATION reg, *preg = ® reg.handler = (DWORD)myHandler; //取得當前異常處理鏈的“頭” DWORD prev; _asm { mov EAX, FS:[0] mov prev, EAX } reg.prev = (EXCEPTION_REGISTRATION*) prev; //注冊! _asm { mov EAX, preg mov FS:[0], EAX } //產生一個異常 int j = 10 / g_div; //異常,除零溢出 } int main() { bar(); return 0; } /*-------輸出------------------- In the exception handler Just a demo. exiting... ---------------------------------*/ 注重EXCEPTION_REGISTRATION必須定義在棧上,並且必須位於比上一個結點更低的內存地址上,Windows對此有嚴格要求,達不到的話,它就會馬上終止進程。 譯者注:本文在網上已經有幾個譯本,但都不完整,所以我決定自己把它翻譯過來。雖然力求信、雅、達,但鑒於這是我的第一次翻譯經歷,不足之處敬請諒解並指出。 與傳統語言相比,C++的一項革命性創新就是它支持異常處理。傳統的錯誤處理方式經常滿足不了要求,而異常處理則是一個極好的替代解決方案。它將正常代碼和錯誤處理代碼清楚的劃分開來,程序變得非常干淨並且輕易維護。本文討論了編譯器如何實現異常處理。我將假定你已經熟悉異常處理的語法和機制。本文還提供了一個用於VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個,你只需要調用下面這個函數: install_my_handler();
   之後,程序中的所有異常,從它們被拋出到堆棧展開(stack unwinding),再到調用catch塊,最後到程序恢復正常運行,都將由我的異常處理庫來治理。 與其它C++特性一樣,C++標准並沒有規定編譯器應該如何來實現異常處理。這意味著每一個編譯器的提供商都可以用它們認為恰當的方式來實現它。下面我會描述一下VC++是怎麼做的,但即使你使用其它的編譯器或操作系統①,本文也應該會是一篇很好的學習材料。VC++的實現方式是以windows系統的結構化異常處理(SEH)②為基礎的。
  
  結構化異常處理—概述
  
  在本文的討論中,我認為異常或者是被明確的拋出的,或者是由於除零溢出、空指針訪問等引起的。當它發生時會產生一個中斷,接下來控制權就會傳遞到操作系統的手中。操作系統將調用異常處理程序,檢查從異常發生位置開始的函數調用序列,進行堆棧展開和控制權轉移。Windows定義了結構“EXCEPTION_REGISTRATION”,使我們能夠向操作系統注冊自己的異常處理程序。 struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; 注冊時,只需要創建這樣一個結構,然後把它的地址放到FS段偏移0的位置上去就行了。下面這句匯編代碼演示了這一操作:mov FS:[0], exc_regp
  
  prev字段用於建立一個EXCEPTION_REGISTRATION結構的鏈表,每次注冊新的EXCEPTION_REGISTRATION時,我們都要把原來注冊的那個的地址存到prev中。那麼,那個異常回調函數長什麼樣呢?在excpt.h中,windows定義了它的原形:
  
  EXCEPTION_DISPOSITION (*handler)( _EXCEPTION_RECORD *ExcRecord, void* EstablisherFrame, _CONTEXT *ContextRecord, void* DispatcherContext); 不要管它的參數和返回值,我們先來看一個簡單的例子。下面的程序注冊了一個異常處理程序,然後通過除以零產生了一個異常。異常處理程序捕捉了它,打印了一條消息就完事大吉並退出了。
  
  #include #include using std::cout; using std::endl; struct EXCEPTION_REGISTRATION { EXCEPTION_REGISTRATION* prev; DWORD handler; }; EXCEPTION_DISPOSITION myHandler( _EXCEPTION_RECORD *ExcRecord, void * EstablisherFrame, _CONTEXT *ContextRecord, void * DispatcherContext) { cout << "In the exception handler" << endl; cout << "Just a demo. exiting..." << endl; exit(0); return ExceptionContinueExecution; //不會運行到這 } int g_div = 0; void bar() { //初始化一個EXCEPTION_REGISTRATION結構 EXCEPTION_REGISTRATION reg, *preg = ® reg.handler = (DWORD)myHandler; //取得當前異常處理鏈的“頭” DWORD prev; _asm { mov EAX, FS:[0] mov prev, EAX } reg.prev = (EXCEPTION_REGISTRATION*) prev; //注冊! _asm { mov EAX, preg mov FS:[0], EAX } //產生一個異常 int j = 10 / g_div; //異常,除零溢出 } int main() { bar(); return 0; } /*-------輸出------------------- In the exception handler Just a demo. exiting... ---------------------------------*/ 注重EXCEPTION_REGISTRATION必須定義在棧上,並且必須位於比上一個結點更低的內存地址上,Windows對此有嚴格要求,達不到的話,它就會馬上終止進程。
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved