對棧的一些理解

2021-08-17 12:04:59 字數 1858 閱讀 6541

之前總結過一篇有關函式棧幀的部落格:

函式棧幀以及呼叫約定相關的一些總結

但是感覺自己還是有一點知識點沒有弄懂,今天中午跟郭哥吃過飯一起**有關殼的問題的時候,順便把這個問題請教了一下郭哥,終於弄明白了,在此要特地感謝他,這裡把一些心得體會寫出來;

先看一幅圖(選自ida權威指南):

注意圖中是基於esp的棧幀!!!

下面是對demo_stack frame函式中bar的呼叫**為例:

push dword [esp+4];//push y,1th

push dword [esp+4];//push z,2th

call bar

add esp,8

棧中資料

對應位址

。。。。。。

。。。。。。

data1

addr1

data2

addr2

data3

addr3

。。。。。。

結合上面這幅圖講講:

esp和ebp都是暫存器,esp始終指向棧頂的意思是:esp這個暫存器裡面始終存放的是棧頂的位址,只不過這個棧頂位址很有可能是經常變化的,棧頂所對應的乙個」容器」裡面存放了乙個資料,這個資料就是被壓入棧的資料(其實棧中其他資料也類似,就是說乙個資料對應乙個位址),同理ebp也是這樣去理解!

對上面那段**(這段**是與基於esp的棧幀對應的)的解釋:

根據上面那副圖的偏移量,1處的push準確的將區域性變數y壓入棧中;初看起來,似乎2處的push錯誤地再次引用了區域性變數y,然而,這裡是基於esp的棧幀!結合上表來理解,假設執行完push y之後,此時棧頂為addr2,即esp這個暫存器裡面存放的是addr2的位址,而在這一步之前棧頂為addr3(esp這個暫存器裡面存放的是addr3的位址),即進行了一次push y操作之後,棧頂被抬高了,棧頂是變化的!此時esp中存的是addr2,再壓一次棧push z,其所對應的指令為push [esp + 4] (這裡指令中的esp指的是addr2),這一步之後,棧頂又會變成addr1.

分步解析一下:假設原來棧是這樣的:

esp指向1000這個位址這裡:

棧中資料

對應位址

。。。。。。

。。。。。。

z1000

y1004

buffer

1008

。。。。。。

執行push y之後:esp指向996了,esp變化了,此時此時z所對應的位址仍然為1000,但是用esp表示的話則為esp+4,而z則就用[esp+4]表示,所以圖中push z的時候寫為 push dword [esp+4]:

棧中資料

對應位址

。。。。。。

y996

z1000

y1004

buffer

1008

。。。。。。

esp是乙個暫存器,這個暫存器裡面存放的是乙個位址,同時這個位址可能是不斷變化的.

看幾條指令(基於ebp的棧幀):

push ebp;//把ebp裡面的位址壓入棧中儲存了起來;這一步作用:儲存上乙個棧幀的底部

mov ebp,esp;//把esp裡面的位址放入ebp暫存器裡面;此時esp和ebp指向同乙個位址,即棧頂和棧底重合;這一步作用:設定新棧幀的底部

sub esp,0x50;//設定新棧幀的頂部,為新棧幀開闢空間

對Linux inode的一些理解

檔名 inode device block 一 inode是什麼?理解inode,要從檔案儲存說起。檔案儲存在硬碟上,硬碟的最小儲存單位叫做 扇區 sector 每個扇區儲存512位元組 相當於0.5kb 作業系統讀取硬碟的時候,不會乙個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次...

對EK的一些理解

首先是網路流問題的提出 乙個源點,乙個匯點,不斷又源點向匯點輸送,其中路徑上有最大速度,求匯點收貨的最大速度是多少。在求之前可以先模擬一下過程如果源點現在只能出乙個單位的貨,那麼他會找乙個未達到最大速度的路進行運輸,接著我們不斷將運輸的量放大,即不斷地從起點開始尋找增廣路,每次都對其進行增廣,直到源...

對SharedNothing的一些理解

share nothing 每乙個cpu都有私有記憶體區域和私有磁碟空間,而且2個cpu不能訪問相同磁碟空間,cpu之間的通訊通過網路連線。share memory 多個cpu共享同一片記憶體,cpu之間通過內部通訊機制 interconnection network 進行通訊 share disk...