關於棧幀最重要的事

2021-08-20 07:01:01 字數 2300 閱讀 3605

關於棧幀,我們需要了解一下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中國遠不止這些,可以說,每乙個熱愛技術...