第十八課 幾條跟堆疊扯上關係的彙編指令

2021-10-10 02:19:37 字數 2532 閱讀 8249

堆疊算是非常重要的結構了,今晚講講它是怎麼設計的,最後講幾個跟堆疊相關的彙編指令。

之前學過那些通用暫存器,讀取方便,而且快速,但是有乙個問題:就是暫存器有大小限制,資料量大的時候,暫存器就不夠用了。為了實現訪問大量的資料,並且能快速讀取資料,前人發明了堆疊的結構。

堆疊的結構是這樣的,分配一段連續的記憶體,定義兩個變數base(棧底)、

top(棧頂)。

base(棧底)裡面儲存乙個位址,記錄該連續記憶體(堆疊)的起始位址。

top(棧頂)裡面儲存乙個位址,記錄該連續記憶體(堆疊)的結束位址。

這兩個變數儲存棧底、棧頂的記憶體位址,這兩個變數的值(記憶體位址)分別儲存通用暫存器ebp和

esp中。

說那個多,來點實在的,看看od中的堆疊長什麼樣的吧。

可以看到堆疊就是一塊連續的記憶體,只不過這段連續的記憶體的開始位址儲存在ebp暫存器中,結束位址儲存在

esp中。這麼看,其實堆疊也沒想的那麼複雜。大家可能也注意到

od的堆疊中棧頂的位址的背景色是深黑色的。

向棧中放入乙個數(假設4個位元組)時,

top(棧頂)的值減

4。可以看下面的示意圖。

向棧中放入乙個數的過程,叫入棧

。在windows系統中,棧是向低位擴充套件的,所以入棧的時候位址是減去乙個數。

在od中執行了一條入棧的命令,可以看到這樣的結果。

從棧中取出乙個數(假設4個節字)時,

base

(棧底)的值加

4。可以看下面的示意圖。

從棧中取出乙個數的過程,叫出棧

可以看到出棧時,只是把棧頂的位址改變,並沒有去刪除原來棧頂的值。

在od中執行一條出棧的命令,可以看到原來棧頂的值還是存在記憶體中的。

如果要讀取棧中間的某個值,可以通過棧頂或棧底加上乙個偏移量的方式去讀取。

可以看到用這種方式讀取記憶體的資料非常快,直接加偏移量就能讀取記憶體中的值。

入棧時,在od中可以發現,

esp中的值減了

4,棧頂上移,並且把值放入到棧頂中。我們可以用已經學過的指令實現這一過程。

mov dword ptr ds:[esp-4],0xa

sub esp,0x4

當然還有其他的方式實現。

其實彙編中還有乙個更好用的指令實現入棧的過程:push指令。

push指令

格式:push r32/r16/m16/m32/imm8/imm16/imm32

例子:push eax :把

eax暫存器中的值壓入棧中。

執行前棧的情況

執行後棧的變化情況

出棧時,也可以用已經學過的指令來實現。

mov eax, dword ptr ds:[esp]

add esp,0x4

當然彙編中也有一條命令實現出棧的過程:pop指令

pop指令

格式:pop r16/r32/m16/32注意pop後面不能是立即數,因為pop後面要有乙個容器接收從棧中取出的數。

例子:pop ecx :把棧頂的值取出放入到

ecx暫存器中。

執行前棧的情況

執行後棧的情況

這篇文章就寫這麼多吧,本來還想寫lea、

call

、ret

等指令的,留到下次吧。

寫於2020.6.12 22:55

Go語言第十八課 CGO

可借助cgo實現go語言對c的呼叫,下面展示幾種呼叫方式。c 內容如下 include include include char test hello const char name int main 執行結果 yuyong hello go 如下 package main include incl...

日本語 第十八課

第十八課 攜帯電話 小 手機便的很小了 音 大 電視的聲音便大了 息子 醫者 兒子成為了醫生 部屋 綺麗 請把屋子收拾乾淨 風邪 感冒怎麼樣了啊?昨夜 薬 飲 昨天吃藥了,但是還沒有好轉 旅行 荷物 軽 旅行箱還是輕點好.軽 是啊,盡可能的變輕了.嬢 你的女兒多大了?今年 七歳 今年,已經7歲了.啊...

孫鑫 第十八課ActiveX控制項

說明 activex控制項有三個要素 屬性,方法,事件 屬性比如button控制項的顯示文字,名字等。屬性值包括stock屬性和custom屬性,其中stock屬性為控制項固有屬性,即mfc封裝的屬性,例如前景色 背景色等。而custom屬性則為使用者自己定製的屬性,在新增custom屬性時要指定外...