關於棧幀,我們需要了解一下c/c++程式記憶體的分配,如圖所示:
棧區:由編譯器自動分配釋放,存放為執行函式而分配的區域性變數、函式、引數、返回值資料、返回位址等。棧區位址依次逐減,與堆區相對而生。
棧幀:函式的呼叫過程中為函式開闢棧空間,用於本次函式的呼叫中臨時變數的儲存、現場保護。這塊棧空間就是函式棧幀。
乙個資料結構——棧,棧頂與棧底。
兩個操作——push(入棧)與pop(出棧)。
暫存器——eax、ebx、ecx、edx (通用暫存器)
ebp 棧底暫存器(基址暫存器)
esp 棧頂暫存器
eip 指令暫存器(程式暫存器)
部分彙編——call(每人將當前正在執行指令的下一條指令的位址壓入棧 中,並且跳轉至目標函式的位址,開始過程呼叫。)
ret (彈出棧頂位址,將資料放入eip)
vc++6.0對棧幀進行研究(不同平台下操作,原理相同偏移量不同)
#include
#include
int add(int
x,int
y)int main()
將以上**進行除錯,轉成組合語言,開啟暫存器與記憶體。
mian函式及臨時變數部分
此時暫存器與記憶體如下
棧區的情況如下
push eax //esp下移,b_eax
0040108a mov ecx,dword ptr [ebp-4]
0040108d push ecx //esp下移,a_ecx
0040108e call @ilt+0(add) (00401005)
//esp下移,存入00401093
add函式棧幀部分
4: int add(int x,int y)// 21
int add(int x,int y)// 3
2.函式內部呼叫函式,返回方式的研究
#include
#include
void bug()
int add(int
x,int
y)int main()
在add函式中呼叫bug函式,返回值返回到bug函式中,但是編譯器會崩掉,所以呼叫完bug函式後最終還是要返回到main函式中
這裡寫描述
bug要返回,首先得找自己的返回值
那就先來研究一下函式內部的第乙個變數和第乙個引數的關係:
void fun(int
x)
void bug()
但是執行的時候編譯器依然會崩掉,原因:
呼叫bug函式時,是指標跳轉過去,沒用call指令,也就是沒有進行push操作
但是返回的時候執行了ret指令,也就是多pop了一次,即esp變大了乙個位址,
所以還需將esp再減去4;
在c語言中插入組合語言:–asm
__asm
這樣就成功的從bug函式中返回到了main函式中. 最重要的事
今天趙隊讓我寫乙份自傳或大學生活感悟,雖然一向不會寫這樣的文章,但還是想了一些東西。在生活中的某乙個階段,我們往往會有乙個 現階段最重要的東西 在這一階段做事時,要把握住這個最重要的東西,是某個原則也好,某個理念也好,總之會有乙個核心。但今天再回首大學四年時,發現那些陳年舊事早已忘記。什麼時候做的什...
投資最重要的事讀後感 把時間留給最重要的事
把時間留給最重要的事 是德國賽洛特爾 韋特博士的一本書名字,這是一本關於時間管理的書。時間對每個人來說每天都是24小時,不會多1分,也不會少1秒。但在同樣的時間裡,每個人的所得卻大不相同,原因何在?在於時間的計畫 統籌與管理,更在於在一定的時間內選擇所做事情的重要與否上。乙個人要想獲得成功,成就一番...
最重要的就是做正確的事
我們是誰?不管我們是否承認,軟體正在吞噬世界。infoq中國掌門人霍泰穩常說,我們要做好技術社群的看門人。在過去的八年裡,秉持著促進軟體開發領域知識與創新的傳播的理念,我們將最前沿 最高端的技術傳遞給需要的人,發表了數千篇高質量的原創和翻譯文章。當然,infoq中國遠不止這些,可以說,每乙個熱愛技術...