原來我以為在c語言中指標已經是非常麻煩了,沒想到棧幀給我甜蜜一擊,但最後一路學習下來也不是多麼麻煩的事。
首先我們得明確為什麼有函式,其作用是:在面向過程語言的重要組成成分,它將具有相同功能的語句組合到一塊,便於我們使用,提高程式可讀性,減少**量。
以main函式為例,在使用過程中首先呼叫__tmaincrtstartup函式,然後又呼叫maincrtstartup函式,而每一次的函式呼叫就是乙個過程——函式的呼叫過程;
在這個過程中我們要為函式開闢棧空間,用於臨時變數的儲存、現場的保護(函式的返回值和引數、呼叫前暫存器的狀態,呼叫前棧幀的頂部和底部的位址),這塊棧空間我們稱之為
函式棧幀。
由c語言的記憶體分布空間可得,在不斷地函式過程中,棧向下增長,那麼具體的呼叫過程是怎麼樣的嘞?舉一段**表示說明(本次**在vc++6.0環境下執行):
很簡單的一段**,將其對應彙編**一步步開始進行分析,在此之前我們了解一下關於彙編的基本知識:
暫存器:esp棧頂指標、
ebp是訪問堆疊底指標——訪問某時刻的棧頂指標,以方便對棧的操作;
eax是"累加器"(accumulator), 它是很多加法乘法指令的預設暫存器、ebx
是"基位址"(base)暫存器, 在記憶體定址時存放基位址、ecx
是計數器(counter), 是重複(rep)字首指令和loop指令的內定計數器、edx
則總是被用來放整數除法產生的餘數。
指令一、main函式棧幀的創立:
乙個函式的棧幀用ebp和esp這兩個暫存器劃定範圍。暫存器esp始終指向棧的頂部,也即指向當前函式棧幀的頂部。而ebp暫存器指向函式棧幀的乙個固定位置,所以ebp暫存器又被稱為幀指標。這兩個暫存器的詳細操作方式為:函式呼叫時上一級呼叫者的幀底被壓入當前ebp內容所指的位址,也就是當前幀的幀底位置儲存了上一級呼叫者的ebp指標值(幀底),而每個ebp的前乙個單元存放的就是當前函式的返回位址(它是由呼叫者在call指令中入的棧)。這樣就可以根據當前ebp的值回溯出整個任務的呼叫棧(呼叫過程)。
二、add函式的呼叫,首先形參例項化(具體過程不表,但具體要用到call命令跳轉至add函式的**執行處);
整個函式呼叫到這裡就結束了,以後將繼續完善~
組合語言典型例子詳解 組合語言典型例題
典型例題 與考試題型,考試範圍相近 應用程式具有 個基本段,可執行指令應該儲存於 aa 段b 資料段c 堆疊段d 附加段2.8 位補碼f3h 要擴充套件成 位補碼應該是 d,這樣其真值才不變。a f0f3h b 00f3h c 10f3h d fff3h 3.mov ebx 8 eax 指令的目的運...
組合語言 函式呼叫棧
當發生函式呼叫的時候,棧空間中存放的資料是這樣的 1 呼叫者函式把被調函式所需要的引數按照與被調函式的形參順序相反的順序壓入棧中,即 從右向左依次把被調函式所需要的引數壓入棧 2 呼叫者函式使用call指令呼叫被調函式,並把call指令的下一條指令的位址當成返回位址壓入棧中 這個壓棧操作隱含在cal...
組合語言3 1 3 5小結 棧
1.字在記憶體中儲存時,佔兩個位元組,即兩個位址連續的記憶體單元,其中x86中,字的低位存放在低位址,高位存放高位址單元。2.mov 指令訪問記憶體單元格式,mov al,address 其中address 只能是資料的偏移位址,資料的段位址存放在ds資料段位址暫存器中。3.mov,add,sub具...