6.栈、栈帧
棧(Stack)的用途廣泛,通常用于存儲局部變量、傳遞函數參數、保存函數返回地址等。調試程序時需要不斷查看棧內存,所以掌握棧很重要。
棧是FILO(First?In?Last?Out,后進先出)這個都知道。但是在看匯編的時候一定要注意一些對應的相關細節。比如函數調用的時候,反匯編看到的參數進棧順序是倒著的等。
棧的特征
內存結構如下:
?
一個進程中,棧頂指針(ESP)初始狀態指向棧底端。執行PUSH命令將數據壓入棧時,棧頂指針就會上移到站頂端。執行POP命令從棧中彈出數據時,若棧為空,則指針重新移動到棧底端。棧時一種由高地址向低地址擴展的數據結構,是由下往上擴展的(逆向擴展)。
所以?向棧壓入數據時,棧頂指針減小,向低地址移動;從棧中彈出數據時,棧頂指針增加,向高地址移動。初始的時候棧頂指針指向占地。
?
棧幀(Stack?Frame)?棧幀在程序中用于聲明局部變量、調用函數。
棧幀就是利用EBP(棧幀指針,請注意不是ESP)寄存器訪問棧內局部變量、參數、函數返回地址等的手段。ESP寄存器承擔著棧頂指針的作用,而EBP寄存器則負責形式棧幀指針的職能。程序運行中,ESP寄存器的值隨時變化,訪問棧中函數的局部變量、參數時,若依ESP值為基準編寫程序會十分困難,并且也很難使CPU引用到準確的地址。所以,調用某函數時,先要把用作基準點(函數起始地址)的ESP值保存到EBP,并維持在函數內部。這樣,無論ESP的值如何變化,以EBP的值為基準(base)能夠安全訪問到相關函數的局部變量、參數、返回地址,這就是EBP寄存器作為棧幀指針的作用。
?
提示:某些優化選項可能會優化掉棧幀。
源代碼vs2015?C++
編譯運行(Debug)之后OD加載上,找到add函數,看下棧幀操作。
?
?
總結
- 上一篇: Docker-整理
- 下一篇: 7.破解的最简单例子