彙編基礎一日一學習5

大家好,今天我給大家講解的是棧,今天這節課程也非常重要。這對你以後調試程序是非常有幫助的。因爲我們程序中的局部變量以及一些函數的參數都是棧中分配內存的。棧也是由我們編譯器自動分配釋放的。    

    那麼棧到底是什麼呢?棧是一種具有特殊的訪問方式的存儲空間。它的特殊就是在於最後進入這個空間的數據,最先出去。

    舉個例子,假如這時我們有3個動物。貓咪、猴子、兔子。那麼我們按先後的順序我們先把貓咪放進棧中,然後再把猴子放到棧中,最後把兔子放到棧中。那麼此時,大家可以看到。兔子現在存在棧頂。那麼此時我們取出的就是兔子了。而最先放進去的時貓咪,它則最後取出。這就是棧的“後進先出”的特性。自己如果不理解,在家裏拿個茶缸,然後找幾個物品,按先後順序把物品放進去,然後在取出來。自己來理解下“後進先出”這個特性。
黑客防線、彙編基礎一日一學習5


我們目前的cpu都有棧的設計。例如80386cpu等。。。。這些cpu也提供了相應的指令來以棧的方式訪問內存空間。這也表示我們編譯的程序被映射到內存以後有一段棧空間供我們訪問。

問題來了?我們怎麼才能知道我們棧空間在那裏呢。
呵呵還記得之前講解的eip寄存器嗎。 我們peloader將我們的程序映射到內存空間以後,將程序的入口點賦值給我們的eip寄存器。這樣cpu讀取eip寄存器的值就可以將我們入口點的彙編指令讀取並運行了。。那麼從這裏就可以下結論,我們棧區的內存地址,肯定也有相應的寄存器存儲。

沒錯,這個寄存器就是esp寄存器。程序第一次被PE loader映射到內存,那麼Peloader會把棧區的內存偏移地址賦值給esp寄存器。

這裏我們棧區的地址也知道如何訪問了。。那麼像棧這麼有個性的內存空間,肯定也有個性的指令來訪問並存取數據吧。沒錯,棧提供了兩個“存”“取”的指令,“push” 和“pop”。
這兩個指令一個“存”一個是“取”。也可以說一個是“入”一個是“進”。  這裏我用“存”和“取”來表示,大家會更好的理解些。。比如push eax 就是將eax寄存器的值存入棧中。。
pop eax 就是將eax取出堆棧。

但是這裏注意了。剛剛我已經說了,esp寄存器是存放棧區的內存地址的。但是如果一旦我們通過push將一段數據存入堆棧,那麼如果esp不會自動增加或減少大小。那麼它就over了。下次存入的時候就會將之前的數據給覆蓋。還好,聰明的Intel公司,已經想到了這一點。
但是不要慌張,我們存入數據我們的esp寄存器應該相應的增加對吧?
但是我們程序被映射到內存以後,相應的是高地址的數據存入高地址,低地址的數據存入低地址。不明白嗎?去看看上節課。或者拿C32asm打開一個文件。文件最底部的數據映射到內存以後也是在地址最高處的。
所以壓入堆棧,我們的數據增加,相應的偏移卻是減少。


每次我們通過push存入數據它esp寄存器的值就會相應的禁燒我們存入數據的字節大小。舉個例子
例如此時 eax =00402500h  esp寄存器=00200000h
執行 pusheax的時候esp也相應的減少  
此時 esp = (00200000 –4)h  

此時我們如果想取數據的話。
pop eax 就可以將esp寄存器中的偏移地址的數據取出並存放到 eax寄存器中。
數據取出來了,相應的數據減小。但是我們的偏移卻增加了。因爲我們每次存取棧都要通過esp寄存器才能知道棧的位置,所以我們這裏可以把esp歸結爲esp永遠是指向棧頂的。
數據取出來,此時我們棧沒了數據相應的地址也向下降了相應數據字節的大小。但是我們的內存是越深處地址越高。所以此時我們的地址是增加了。
所以popeax寄存器執行後  esp =(00200000 -4 +4)

不知道大家是否明白了?如果不懂的話多讀幾次。

因爲今天這節課程比較多,如果全部講的話怕大家接受不了。 接下來我給大家寫一個實例。
來詳細的講解下。

如果我們將0040000h – 00400020h , 初始狀態棧是空的,那麼此時esp指向的地址是多少?

切記:記得一定要把上節課的內容也要嵌入進來。。怕大家不能理解。esp永遠指向我們棧頂元素。棧而且它最初指向的就是棧頂,也就是我們棧空間的最頂部。記住內存越深,地址也就越高。哈哈

正確答案:esp = 00400021h 。

所以esp指向的地址,必須夠我們寫入4個字節的數據(因爲80386的數據線一次只能傳送4個字節的數據)。並且寫入後不能發生越界行爲。

怕大家不能消化,今天就講這麼多吧。。。。。接下來來用幾個小作業。來鞏固下知識。


小作業:
(1)        假如此時eax= 00402500h , esp = 00400000h。那麼執行Push eax 後, esp寄存器等於多少???
  
(2)        假如此時eax= 000001h , esp 00003020h。執行pop eax指令後, esp寄存器等於多少??

(3)   假如此時我們將00300000h – 0030001Ah作爲棧空間,初始狀態棧是空的。此時esp等於多少???
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章