如果你是程式設計新手,你確信對系統棧結構有所了解嗎?

2021-08-30 00:09:26 字數 1889 閱讀 5975

如果你是程式設計新手,你確信對系統棧結構有所了解嗎?

首先宣告這篇文章是絕對的原創,希望對新手能起到拋磚引玉的作用。

你對系統棧了解多少?__cdecl,__stdcall,__thiscall與棧有什麼直接的聯絡?

彙編對你的工作興許沒什麼幫助,但我還是請求你看完下面的示例,看看下面的分析,你會從中看懂你應該懂得的東西。

**段一、

#include

using namespace std;

int __cdecl fun(int a,int b) //如果這裡換成__stdcall又會怎麼樣?

cout<<"show a value:"int _tmain(int argc, _tchar* argv)

__asm

push 1 //__cdecl的呼叫約定,1入棧等同於b=1

push 2 //接著是2入棧,等同於a=2

call fun //能不能直接換成jmp fun呢?

add esp,8 //為何新增此條語句

cout<<"thank you!"一段典型的c/c++內嵌彙編的**,為了分析更直觀,先請有編譯器的新手們在機器上執行一下,當然執行的結果並不會令你驚奇!程式輸出了2和 1,thank you! 我們並不能把腳步停留在這表面的東西,還有很多的東西需要我們來挖掘。帶著我**中的疑問,go on...

換成__stdcall的呼叫約定,**顯示2和1後就直接崩潰了,why?這是因為,被__stdcall修飾的函式自行會調整棧結構,等到函式fun return返回時,esp所指的位置已經還原成main函式起初的位置,而再次對其施加指令add esp,8無非是畫蛇添足了,這就叫"我用的我還原"; 而_cdecl對棧結構的維護不同,叫"我用你還原",因此,上述**_stdcall和__cdecl修飾的fun函式最大的差別在於,在內嵌的彙編**中寫不寫add esp,8這句**。可能有的新手會故意把這條**寫成add esp,4 可是一執行發現不管用的是__stdcall還是__cdecl,**都會崩掉,why? add esp,8 不是隨便寫的,記憶體的彙編**中不是有push 1 ,push 2,兩句**嘛。這表示程式執行的棧結構中多了8個位元組,乙個是1,乙個是2。說到這裡,可能有的新手還是不死心,於是寫下了sub esp ,8 對不起**還是崩了。why?為何是加上8而不是減8呢,如果你假設的win32系統棧的成長方向是由低到高,恭喜你sub esp,8是正確的,可偏偏是win32系統棧的成長方向是由高到低。因此,最先壓棧的東西占領了更高的位址位,講到這裡或許都認為問題已經明瞭化了,no,no...我們還得go on...

call fun指令能不能換成jmp fun呢?從功能上來說,call 是由一系列的push指令和一條jmp指令組成的因此,無論如何就指令的執行效率來說,jmp肯定相對call更高效。但是這裡用jmp替換call指令是絕不可以的,答案很簡單,call指令會對棧進行必要的維護其中必有的隱含指令是push eip ,看到沒有call指令被呼叫後,必須把指令指標壓入棧中,call在給自己留後路(必須記得是誰呼叫了我,我還得回家). jmp是那種絕不做任何停留勇往直前,也絕不回頭。因此,在換成jmp指令後,根本就看不到thank you的輸出了。

另外,如果你看到這裡還沒有睡著的話,那我們就講講_cdecl和__stdcall另外的一些區別,__stdcall函式一般不允許函式以變參宣告,像這樣 int __stdcall fun(int a,...) ,這種宣告是__cdecl獨有的,是c/c++語言獨有的,以__stdcall宣告不定引數的函式形式必定給棧結構帶來毀滅性的災難!

最後談談__thiscall,這是c/c++類中成員函式的呼叫約定,他在形參個數固定的情況下等同於__stdcall,個數不定是等同於__cdecl,還有幾個特殊的呼叫約定(__fastcall,__declspec(naked)),由於用的極少,不在累贅,感興趣的可以自己找資料看看。

好了就寫這麼多了,同時希望高手們能接續....

如果你是ip,你會怎麼選

如果你是網路層,你更喜歡icmp tcp udp三種報文中的哪乙個?如果你了解mtu和mss,那你應該很容易做出選擇 就像選擇物件一樣,你首先要了解對方是誰,有什麼優缺點,能給你帶來什麼 internet control message protocol,ip層的乙個組成部分,主要用來傳遞差錯報文以...

如果你是班傑明 富蘭克林,會怎樣學習程式設計?

優秀的程式設計方法是極難教的。程式設計書籍大抵都是這樣開頭的 這是x方法的例子,還有下面這個例子 教教基礎是容易的,因為基礎知識也就那麼多。難就難在,要教明白每種選擇帶來的結果。一般我們會建議多寫 慢慢提高水平。這是必要但非充分條件。要想學的更好,我們還要判斷應該寫哪些 以及如何改善這些 我們接下來...

如果你是我的傳說

如果你是我的傳說 幽谷,有我 最驕豔的靈魂 傲立風中 美麗的無奈 為誰開 為誰紅 寂寞冰心 渴望 襲我暗香 兩相望問古今 情愛難為幾何 夢裡疏香暗度 正是消魂時節 花身應惜惜 投懷 送抱 君念我醉狂無?靜靜地看著你 讓我 讀你 眼底最深的曖昧 洩露了內心的渴望 等待你傾吐 最浪漫 最美的 動詞 河灘...