c語言函數有幾種壓棧方式 函數調用 壓棧
C語言中函數參數壓棧方式為什么是從右到左
棧是先入后出的數據結構.
專注于為中小企業提供成都網站制作、成都網站設計服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業神池免費做網站提供優質的服務。我們立足成都,凝聚了一批互聯網行業人才,有力地推動了上1000+企業的穩健成長,幫助中小企業通過網站建設實現規模擴充和轉變。
函數參數從右到左, 那么到函數內部出棧的時候就是從左到右的順序了.
對于普通函數無區別. 但對于可變參函數, 會根據左側參數來決定共計有多少參數, 每個類型是什么.
比如 printf scanf這類的.
于是 就設計成從右到左的壓棧方式了.
關于c語言 壓棧函數
方法很簡單:你講兩個棧都傳進去,類似于 : int pus(SeqStack1 *s, DataType* x1, SeqStack2 *s, DataType* x2)(SeqStack1是你的第一個棧,SeqStack2是第二個棧,DataType是你需要傳進去的數據的類型),然后在這個函數里面先判斷x1 ,x2是否為空,如果為空,則他對應的那個棧不需要壓棧,如果不為空,則執行相應的壓棧操作。
不明白繼續追問!
C語言函數壓棧順序
基本正確,補充一點,參數一般是往寄存器里面放,放不下的情況下,才壓棧。
什么是堆和棧?函數壓棧是怎么回事?
什么是堆和棧?
一個由c/C++編譯的程序占用的內存分為以下幾個部分
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧。
2、堆區(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似于鏈表,呵呵。
3、全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。 - 程序結束后有系統釋放
4、文字常量區 —常量字符串就是放在這里的。 程序結束后由系統釋放
5、程序代碼區—存放函數體的二進制代碼。
函數壓棧是怎么回事?
函數壓棧的本質是參數傳遞
這又跟匯編語言連系起來了.匯編語言的過程即proc可以理解成函數
比如一個最簡單的計算兩數之和函數
如果用匯編來寫估計是這樣的
sub proc
pop ax ;從stack取a 并放在AX寄存器中
pop bx ;從stack取b 并放在BX寄存器中
add ax,bx ; 計算a+b
ret //返回
sub endp
顯然要調用這個函數,你應當先把b值push進stack,然后再push a
因為stack是先進后出的
所以調用匯編像這樣
比如計算4+5
push 5;
push 4;
call sub; //返回值在AX中
在這個例子中先壓5或先壓4得到的結果沒有變化
但大多數程序,如果參數的順序錯誤將是災難性的
因為不管什么高級語言最終都要編譯成匯編語言,然后是機器語言
同樣下面這個C程序,計算a+b值,必然會編譯成上面的匯編代碼
int sub(int a ,int b) {return a+b;}
所以C在調用這個函數sub時,必須要壓棧(即傳入參數)但這些工作,在C語言里,并不需要你來完成.你只要寫出
sub(7,9);
編譯器在編譯成匯編時就會自動完成相關的壓棧工作.
根據函數調用方式和參數壓入順序目前存在三種約定:
stdcall
cdecl
fastcall
這都相關壓棧順序和棧的清理工作約定
他們的細節都不相同,但有一點是肯定的,參數比須從右向左壓入棧中
stdcall中 函數必須自已清理棧
cdecall 由調用者清除堆棧 C的默認函數調用方式 所以這樣C支持可變參數
fastcall 是把函數參數列表的前三個參數放入寄存器eax,edx,ecx,其他參數壓棧
源代碼:
int function(int a, int b)
{
return a + b;
}
void main()
{
function(10, 20);
}
1.__cdecl
_function
push ebp
mov ebp, esp
mov eax, [ebp+8] ;參數1
add eax, [ebp+C] ;加上參數2
pop ebp
retn
_main
push ebp
mov ebp, esp
push 14h ;參數 2入棧
push 0Ah ;參數 1入棧
call _function ;調用函數
add esp, 8 ;修正棧
xor eax, eax
pop ebp
retn
2.__fastcall
@function@8
push ebp
mov ebp, esp ;保存棧指針
sub esp, 8 ;多了兩個局部變量
mov [ebp-8], edx ;保存參數 2
mov [ebp-4], ecx ;保存參數 1
mov eax, [ebp-4] ;參數 1
add eax, [ebp-8] ;加上參數 2
mov esp, ebp ;修正棧
pop ebp
retn
_main
push ebp
mov ebp, esp
mov edx, 14h ;參數 2給EDX
mov ecx, 0Ah ;參數 1給ECX
call @function@8 ;調用函數
xor eax, eax
pop ebp
retn
3.__stdcall
_function@8
push ebp
mov ebp, esp
mov eax, [ebp] ;參數 1
add eax, [ebp+C] ;加上參數 2
pop ebp
retn 8 ;修復棧
_main
push ebp
mov ebp, esp
push 14h ;參數 2入棧
push 0Ah ;參數 1入棧
call _function@8 ;函數調用
xor eax, eax
pop ebp
retn
本文名稱:c語言函數有幾種壓棧方式 函數調用 壓棧
分享地址:http://www.xueling.net.cn/article/dojdcdi.html