原貼地址:
【 聲明:版權所有,歡迎轉載,請勿用於商業用途。 聯繫信箱:feixiaoxing @163.com 】
在繼續圖的討論之前,我們今天開個小差,討論一下函數堆棧的基本原理。有過編程經驗的朋友都知道,堆棧調試是我們在程序開發中經常應用的一個功能。那麼大家有沒有想過,函數堆棧是怎麼開始的啊?其實我們可以自己寫一個函數堆棧輸出函數分析一下。
因爲一般來說,函數的壓棧過程是這樣的:
| 參數三 |
| 參數二 |
| 參數一 |
| address|
| ebp |
| variable | <--------------------------------- ebp
那麼堆棧中的內容是怎麼打印的呢?
- void stack_print()
- {
- int var_ebp;
- __asm mov var_ebp, ebp;
- printf("%08x\n", *((int*)(var_ebp) + 1));
- }
- void stack_print()
- {
- int var_ebp;
- __asm mov var_ebp, ebp;
- do{
- printf("%08x\n", *((int*)(var_ebp) + 1));
- var_ebp = *(int*)(var_ebp);
- }while(var_ebp != 0x0);
- }
大家這樣在VC編譯的時候把Generate mapfile選上,就可以生成對應的*.map文件了。文件中包含了當前文件中主要函數的起始地址,而且是按照從低到高依次排序的。所以只要尋找到對應的函數起始,判斷我們的函數返回地址是不是在這個函數中間,那麼就可以找到對應的函數名稱了。
總結:
(1)今天總結了一下函數堆棧顯示的基本原理;
(2)知道函數的基本原理之後,方便我們從本質上理解很多問題。即使很多CPU的處理方式和X86不同,我們也可以通過類似的方法快速掌握;
(3)堆棧原理十分重要,朋友們應該好好了解一下。