c/c++堆棧檢查函數詳解

c/c++運行期庫包含一個堆棧檢查函數,當編譯源代碼的時候,編譯器在恰當的時候(這個在下面講)生成對該函數的調用
下面我們看個函數

void SomeFunction()
{
    int nValues[4000];
    nValues[0]=0;
}

該函數需要16000個字節的堆棧空間,編譯器生成的用於分配該堆棧空間的代碼只是將堆棧指針遞減16000個字節,但是在程序試圖訪問該內存之前,系統並不會將物理存儲器分配給堆棧的較低區域

這裏需要說明下,堆棧指針的初始地址是最高的,線程運行過程中,由於不斷的分配內存,堆棧指針是下移的
這裏附上堆棧結構的講解篇
http://blog.csdn.net/baidu_25539425/article/details/78927326

由於物理存儲器不會被提交給較低區域,所以,我們需要在適當的時候運行堆棧檢查函數,那麼什麼時候是適當的呢
就是當我們需要的內存的數量大於CPU系統的頁面大小的時候,就需要進行堆棧檢查。當然這些全部是由系統完成的

以前我們講過,intel系的CPU的頁面大小爲4KB,Alpaha系的CPU的頁面大小爲8KB,所以在windows系統下,只要函數所需的內存的數量大於4096個字節,系統就會自動調用堆棧檢查函數

下面我們來展示一段堆棧檢查函數的僞代碼

#ifdef _M_ALPHA
#define PAGESIZE (8*1024)
#else
#define PAGESIZE (4*1024)
#endif

void StartCheck(int BytesNeedFromStack)
{
    PBYTE pbStackPtr=(CPU's stack pointer);//獲取堆棧指針的地址
    while(BytesNeedFromStack>=PAGESIZE)
    {
        pbStackPtr-=PAGESIZE;//堆棧指針下移
        pbStackPtr[0]=0;//給指針所在的頁面分配物理存儲器
        BytesNeedFromStack-=PAGESIZE;
    }
}

大家可能對pbStackPtr[0]=0這句話不太理解,我前面說過
但是在程序試圖訪問該內存之前,系統並不會將物理存儲器分配給堆棧的較低區域
所以,這句話的意思是訪問該內存,實際上,訪問過後,系統就會把該頁面提交到物理存儲器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章