在繼續圖的討論之前,我們今天開個小差,討論一下函式堆疊的基本原理。有過程式設計經驗的朋友都知道,堆疊除錯是我們在程式開發中經常應用的乙個功能。那麼大家有沒有想過,函式堆疊是怎麼開始的啊?其實我們可以自己寫乙個函式堆疊輸出函式分析一下。
因為一般來說,函式的壓棧過程是這樣的:
| 引數三 |
| 引數二 |
| 引數一 |
| address|
| ebp |
| variable |
那麼堆疊中的內容是怎麼列印的呢?
void stack_print()
上面的**只是列印當前函式的返回位址,那麼如果是連續的函式列印呢?列印到main函式開始呢。
void stack_print()
while(var_ebp != 0x0);
}
上面的**可看到一對位址,那麼怎麼把這些位址和函式名稱對應起來了,那就只能查表了。函式對應的表在**呢?不著急,看了下面的乙個截圖,朋友們就明白怎麼回事了。
大家這樣在vc編譯的時候把generate mapfile選上,就可以生成對應的*.map檔案了。檔案中包含了當前檔案中主要函式的起始位址,而且是按照從低到高依次排序的。所以只要尋找到對應的函式起始,判斷我們的函式返回位址是不是在這個函式中間,那麼就可以找到對應的函式名稱了。
總結:
(1)今天總結了一下函式堆疊顯示的基本原理;
(2)知道函式的基本原理之後,方便我們從本質上理解很多問題。即使很多cpu的處理方式和x86不同,我們也可以通過類似的方法快速掌握;
(3)堆疊原理十分重要,朋友們應該好好了解一下。
一步一步寫演算法(之遞迴和堆疊)
看過我前面部落格的朋友都清楚,函式呼叫主要依靠ebp和esp的堆疊互動來實現的。那麼遞迴呢,最主要的特色就是函式自己呼叫自己。如果乙個函式呼叫的是自己本身,那麼這個函式就是遞迴函式。我們可以看一下普通函式的呼叫怎麼樣的。試想如果函式a呼叫了函式b,函式b又呼叫了函式c,那麼在堆疊中的資料是怎麼儲存的...
一步一步寫演算法(之遞迴和堆疊)
看過我前面部落格的朋友都清楚,函式呼叫主要依靠ebp和esp的堆疊互動來實現的。那麼遞迴呢,最主要的特色就是函式自己呼叫自己。如果乙個函式呼叫的是自己本身,那麼這個函式就是遞迴函式。我們可以看一下普通函式的呼叫怎麼樣的。試想如果函式a呼叫了函式b,函式b又呼叫了函式c,那麼在堆疊中的資料是怎麼儲存的...
一步一步寫演算法(之 A 演算法)
在前面的部落格當中,其實我們已經討論過尋路的演算法。不過,當時的示例圖中,可選的路徑是唯一的。我們挑選乙個演算法,就是說要把這個唯一的路徑選出來,怎麼選呢?當時我們就是採用窮盡遞迴的演算法。然而,今天的情形有點不太一樣了。在什麼地方呢?那就是今天的路徑有n條,這條路徑都可以達到目的地,然而我們在挑選...