您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)什么是C++的堆棧指引,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
我們經(jīng)常會討論這樣的問題:什么時候數(shù)據(jù)存儲在堆棧(Stack)中,什么時候數(shù)據(jù)存儲在堆(Heap)中。我們知道,局部變量是存儲在堆棧中的;debug時,查看堆棧可以知道函數(shù)的調(diào)用順序;函數(shù)調(diào)用時傳遞參數(shù),事實上是把參數(shù)壓入堆棧,聽起來,堆棧象一個大雜燴。那么,堆棧(Stack)到底是如何工作的呢?本文將詳解C/C++堆棧的工作機制。閱讀時請注意以下幾點:
1)本文討論的編譯環(huán)境是VisualC/C++,由于高級語言的堆棧工作機制大致相同,因此對其他編譯環(huán)境或高級語言如C#也有意義。
2)本文討論的堆棧,是指程序為每個線程分配的默認堆棧,用以支持程序的運行,而不是指程序員為了實現(xiàn)算法而自己定義的堆棧。
3)本文討論的平臺為intelx86。
4)本文的主要部分將盡量避免涉及到匯編的知識,在本文最后可選章節(jié),給出前面章節(jié)的反編譯代碼和注釋。
5)結(jié)構(gòu)化異常處理也是通過堆棧來實現(xiàn)的(當你使用try…catch語句時,使用的就是c++對windows結(jié)構(gòu)化異常處理的擴展),但是關(guān)于結(jié)構(gòu)化異常處理的主題太復(fù)雜了,本文將不會涉及到。
1)程序的堆棧是由處理器直接支持的。在intelx86的系統(tǒng)中,堆棧在內(nèi)存中是從高地址向低地址擴展(這和自定義的堆棧從低地址向高地址擴展不同),因此,棧頂?shù)刂肥遣粩鄿p小的,越后入棧的數(shù)據(jù),所處的地址也就越低。
2)在32位系統(tǒng)中,堆棧每個數(shù)據(jù)單元的大小為4字節(jié)。小于等于4字節(jié)的數(shù)據(jù),比如字節(jié)、字、雙字和布爾型,在堆棧中都是占4個字節(jié)的;大于4字節(jié)的數(shù)據(jù)在堆棧中占4字節(jié)整數(shù)倍的空間。
3)和堆棧的操作相關(guān)的兩個寄存器是EBP寄存器和ESP寄存器的,本文中,你只需要把EBP和ESP理解成2個指針就可以了。ESP寄存器總是指向堆棧的棧頂,執(zhí)行PUSH命令向堆棧壓入數(shù)據(jù)時,ESP減4,然后把數(shù)據(jù)拷貝到ESP指向的地址;執(zhí)行POP命令時,首先把ESP指向的數(shù)據(jù)拷貝到內(nèi)存地址/寄存器中,然后ESP加4。EBP寄存器是用于訪問堆棧中的數(shù)據(jù)的,它指向堆棧中間的某個位置(具體位置后文會具體講解),函數(shù)的參數(shù)地址比EBP的值高,而函數(shù)的局部變量地址比EBP的值低,因此參數(shù)或局部變量總是通過EBP加減一定的偏移地址來訪問的,比如,要訪問函數(shù)的第一個參數(shù)為EBP+8。
4)堆棧中到底存儲了什么數(shù)據(jù)?包括了:函數(shù)的參數(shù),函數(shù)的局部變量,寄存器的值(用以恢復(fù)寄存器),函數(shù)的返回地址以及用于結(jié)構(gòu)化異常處理的數(shù)據(jù)(當函數(shù)中有try…catch語句時才有,本文不討論)。這些數(shù)據(jù)是按照一定的順序組織在一起的,我們稱之為一個堆棧幀(StackFrame)。一個堆棧幀對應(yīng)一次函數(shù)的調(diào)用。在函數(shù)開始時,對應(yīng)的堆棧幀已經(jīng)完整地建立了(所有的局部變量在函數(shù)幀建立時就已經(jīng)分配好空間了,而不是隨著函數(shù)的執(zhí)行而不斷創(chuàng)建和銷毀的);在函數(shù)退出時,整個函數(shù)幀將被銷毀。
5)在文中,我們把函數(shù)的調(diào)用者稱為caller(調(diào)用者),被調(diào)用的函數(shù)稱為callee(被調(diào)用者)。之所以引入這個概念,是因為一個函數(shù)幀的建立和清理,有些工作是由Caller完成的,有些則是由Callee完成的。
看完上述內(nèi)容,你們對什么是C++的堆棧指引有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。