日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ebp 函数堆栈esp_对于ESP、EBP寄存器的理解

發布時間:2025/4/5 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ebp 函数堆栈esp_对于ESP、EBP寄存器的理解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

esp是棧指針,是cpu機制決定的,push、pop指令會自動調整esp的值;

ebp只是存取某時刻的esp,這個時刻就是進入一個函數內后,cpu會將esp的值賦給ebp,此時就可以通過ebp對棧進行操作,比如獲取函數參數,局部變量等,實際上使用esp也可以;

既然使用esp也可以,那么為什么要設定ebp呢?

答案是為了方便程序員。

因為esp在函數運行時會不斷的變化,所以保存一個一進入某個函數的esp到ebp中會方便程序員訪問參數和局部變量,而且還方便調試器分析函數調用過程中的堆棧情況。前面說了,這個ebp不是必須要有的,你非要使用esp來訪問函數參數和局部變量也是可行的,只不過這樣會麻煩一些。

這里函數調用約定使用的是_stdcall

通過一段程序理解esp和ebp:

main() {//執行test前

print(int p1,intp2);//執行test后

}

分析下上面程序的調用原理,假設執行print前esp=Q:

push p2;//函數參數p2入棧,esp=Q-4H

push p1;//函數參數p1入棧,esp=Q-8H

call print;//函數返回地址入棧,esp=Q-0CH

//現在進入print內,做些準備工作:push ebp;//保護先前ebp指針,ebp入棧,esp=Q-10H

mov ebp,esp;//設置ebp等于當前的esp

// 此時,ebp+0CH=Q-4H,即p2的位置

// 同樣,ebp+08H=Q-8H,即p1的位置

// 下面是print內的一些操作:sub esp,20H;//設置長度為10H大小的局部變量空間,esp=Q-20H

// ... ...

// 一系列操作

// ... ...add esp,20H;//釋放局部變量空間,esp=Q-10H

pop ebp;//出棧,恢復原先的ebp的值,esp=Q-0CH

ret 8;//ret返回,彈出先前入棧的返回地址,esp=Q-08H,后面加操作數8H為平衡堆棧

// 之后,彈出函數參數,esp=Q,恢復執行print函數前的堆棧;

圖示,注意棧在內存中的生長方向是逆向:

執行push p2;前,esp=Q;

執行push p2;過程中,esp-=4H,p2入棧;

執行push p2;后,esp=Q-4H;

因為參數傳遞和匯編語言有很大聯系,之后會出現較多x86匯編代碼。

該文會先講一下x86的堆棧參數傳遞過程,然后再分析C/C++子函數是怎樣通過堆棧傳遞參數的。

注:匯編語言的過程和C/C++的子函數是一回事。

寄存器參數,存儲器參數和堆棧參數都可以用于x86匯編乃至其他匯編語言傳遞參數的方式。但C/C++在編譯時,編譯器會對子函數使用堆棧參數傳遞方式。

三種參數傳遞方式對比:

1、寄存器參數

mov eal,4

callProc_using_eal

...

2、存儲器參數

.data

temp DB ?

.code

...mov temp,4

call Proc_using_temp

3、堆棧參數

push 4

call Proc_using_stack

1、x86堆棧參數傳遞過程

考慮一個過程add_num,該過程有兩個輸入參數,一個輸出參數。其功能是將兩個輸入參數求和并將其結果輸出。下面這個例子中使用堆棧將3, 4兩個參數輸入到add_num中。

push 3

push 4

call add_num

執行call指令前,堆棧如下:

其中ESP為x86CPU使用的堆棧指針,每進行一次入棧操作,ESP要減4(32位CPU)(圖上堆棧向上地址減小,向下地址增加)

明顯的是,add_num只需要把堆棧中相應的變量取出來使用就可以了。堆棧參數傳遞的確也是這么做,但是卻要稍稍費事一點。

首先給出add_num過程的程序

add_num procpushebpmovebp,espmov eax,[ebp+8]add eax,[ebp+12]popebpretadd_num endp

之前筆者給出的堆棧是CPU執行call指令前的結果,接下來從開始執行call指令一步一步分析堆棧的變化情況。

(1)call add_num

執行call add_num時,ESP減4后將add_num過程的返回地址壓入堆棧,即當前指令指針EIP的值(該值為主程序中call指令的下一條指令(不是push ebp)的地址)

(2)

pushebpmovebp,espmov eax,[ebp+8]add eax,[ebp+12]

此時已經進入add_num過程內部

這一步是為了將esp的值賦予ebp。而將ebp壓入堆棧是為了保護ebp,在add_num過程結束后還要恢復ebp的值。

此時esp指向堆棧中的ebp,而將esp賦予ebp后,ebp便指向了堆棧中自己被保護的值。此時ebp的主要作用是為參數讀取提供絕對地址。比如參數4比ebp所在地址高8Byte(堆棧一個單元是4Byte),則過程中要使用參數4時,使用基址-偏移量尋址即可,即[ebp+8]。

當然這里也可以使用esp達到相同的效果,但是這個例子沒有局部變量。若子過程中有局部變量(局部變量也存放在堆棧里),采用ebp要方便很多。

(3)pop ebp

此時ebp彈出,ebp恢復調用前的值

(4)ret

最后彈出返回地址,程序返回到主程序中,并執行下一條指令

以上為整個堆棧參數傳遞過程。

這里有幾個需要注意的點:

(1)、堆棧幀到底是什么

堆棧幀(stack frame)(或活動記錄(activation record))是一塊堆棧保留區域,用于存放被傳遞的實際參數、子程序的返回值、局部變量以及被保存的寄存器。

實際上堆棧幀就相當于子函數的緩存,當子函數使用的堆棧個數最大時,其所擁有的所有部分構成了這個函數的堆棧幀。

以add_num過程為例,其堆棧幀如下圖灰色部分所示。

(2)、堆棧幀為什么叫做堆棧幀

“堆棧”很好理解,而“幀”的概念在上面那個例子中的確很難搞通。不久后筆者會分析遞歸函數中的堆棧幀增消的現象,那個時候“幀”這個概念體現得淋漓盡致。

(3)、輸入參數3和4留在堆棧里沒有釋放是可以的嗎

上面的例子并沒有釋放參數4和3,只是為了演示,實際上一定會有相應的代碼去釋放它。子函數的堆棧幀是包含其輸入堆棧變量的,當退出子函數時,其所有的堆棧幀必須被完全釋放,否則堆棧就會變得混亂。

釋放參數涉及兩種子函數調用標準,一種是STDCALL標準,一種是C標準。兩種在參數的堆棧傳遞細節幾乎完全相同,不同的是釋放參數的方式。

根據兩個標準重新改寫add_num過程:

STDCALL調用規范

add_num procpushebpmovebp,espmov eax,[ebp+8]add eax,[ebp+12]popebpret 8add_num endp

11. C調用規范

...push 3

push 4

calladd_numadd esp,8

兩種方式的核心思想就是修改esp,使esp指向堆棧參數3和4所在位置的前一個堆棧。但是STDCALL調用規范是在過程內部修改esp(ret 8為將堆棧中返回地址彈出到EIP后,再將ESP加8);C調用規范是在子過程外部,在主調過程修改esp。

另引用這兩種方式的優缺點:

STDCALL不僅減少了子程序調用產生的代碼量(減少了一條指令),還保證了調用程序永遠不會忘記清除堆棧。另一方面,C調用規范允許子程序聲明不同數量的參數,主調程序可以決定傳遞多少個參數。C語言的printf函數就是一個例子

總結

以上是生活随笔為你收集整理的ebp 函数堆栈esp_对于ESP、EBP寄存器的理解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本一区二区三区欧美 | 国产精品23p | 日韩午夜在线观看 | 亚洲成年 | 国产日韩欧美专区 | www四虎精品视频免费网站 | 成人免费视频网站在线看 | 天堂视频在线免费观看 | 高跟av | 中文字幕av播放 | 免费看毛片网站 | 亚洲一区二区自偷自拍 | 国产又粗又硬视频 | 特黄特色大片免费 | 97精品国产97久久久久久春色 | 色婷婷av一区二区三 | 在线欧美色| 国产丝袜一区二区三区 | 91成人入口 | 国产一区欧美一区 | 国产精品入口久久 | 亚洲一区免费看 | 日韩高清不卡在线 | 亚洲国产精品激情在线观看 | 欧美啊v | 精品av一区二区 | 午夜成年人视频 | 波多野结衣91 | 欧美性猛交xxxx黑人猛交 | 亚洲精品乱码久久久久久蜜桃欧美 | 精品欧美一区二区久久久 | 伊人精品久久 | 蘑菇福利视频一区播放 | www.玖玖玖 | 四虎影院永久 | 中文免费av| 国产精品第八页 | 日本一区二区三区四区在线观看 | 日本一级视频 | 久久久久久国产精品日本 | 女人性做爰24姿势视频 | 亲子乱aⅴ一区二区三区 | 一区二区在线免费观看视频 | av2014天堂 | 久久婷婷五月综合色吧 | 69超碰| 日日操av | 超碰人人国产 | 久久短视频 | 精品国产免费人成在线观看 | 无码人妻一区二区三区精品视频 | 综合五月网 | 欧美综合视频 | www.天天综合 | 国精产品一区一区三区在线 | 国产香蕉视频在线播放 | 欧美少妇bbw | 九九热这里只有精品6 | 五月的婷婷 | 免费三级网 | 女人被男人躁得好爽免费视频 | 99精品在线免费观看 | 国产专区一区二区 | 9色在线视频 | 人妻少妇久久中文字幕 | 日本免费一区二区三区 | 国产欧美日韩在线视频 | 91精品999 | 超碰在线c| 日韩另类视频 | 欲色av| 中文字幕第九页 | 黄页av| 久久精品香蕉视频 | 欧美激情第五页 | 女同av在线| 91大神小宝寻花在线观看 | 欧美用舌头去添高潮 | 亚洲激情五月 | 日韩在线观看网址 | 成人国产 | 天天干夜夜干 | 丰满少妇在线观看网站 | 久久婷婷影院 | 色小妹av | 亚洲无吗视频 | 99久久久久久久久 | 99国产精品久久久久久久久久久 | 色老板最新地址 | 亚洲一区二区小说 | 涩涩视频在线播放 | 99热这里只有精品8 国产一卡二 | 色五夜| 欧美色图一区二区三区 | 在线观看国产日韩 | 亚洲欧洲综合在线 | 久久精品性爱视频 | 国产美女精品久久久 | 日本熟妇色xxxxx日本免费看 |