在vc中,呼叫方式有__stdcall,__cdecl,__fastcall,thiscall幾種。其中前三種是一般呼叫所能使用的呼叫方式,thiscall是類物件呼叫成員函式時使用的呼叫方式,當在乙個函式前使用__declspec(naked)修飾時,編譯器不會在函式的內部將不再產生儲存和恢復某些暫存器值的**。
對於__stdcall呼叫方式,所有引數通過棧傳遞,引數壓棧順序為從右到左,並且由被
呼叫的函式平衡棧:
bool __stdcall call(void *a, void *b, void *c, void *d, void *e)
與call(0,0,0,0,0)對應的呼叫彙編**為:
push 0 ; e
push 0 ; d
push 0 ; c
push 0 ; b
push 0 ; a
call ?call@@yghpax0000@z ; call(void *,void *,void *,void *,void *)
對於__cdecl呼叫方式,所有引數通過棧傳遞,引數壓棧順序為從右到左,由呼叫者平衡棧:
bool __cdecl call(void *a, void *b, void *c, void *d, void *e, void *f, void *g)
與call(0,0,0,0,0)對應的呼叫彙編**為:
push 0 ; e
push 0 ; d
push 0 ; c
push 0 ; b
push 0 ; a
call ?call@@yahpax0000@z ; call(void *,void *,void *,void *,void *)
add esp, 14h
對於__fastcall呼叫方式,第乙個引數通過ecx傳遞,第二個引數通過edx傳遞,其它引數
通過棧傳遞,引數壓棧順序為從右到左,由被呼叫的函式平衡棧:
bool __fastcall call(void *a, void *b, void *c, void *d, void *e)
與call(0,0,0,0,0)對應的呼叫彙編**為:
push 0 ; e
push 0 ; d
push 0 ; c
xor edx, edx ; b
xor ecx, ecx ; a
call ?call@@yihpax0000@z ; call(void *,void *,void *,void *,void *)
對於thiscall呼叫方式,this指標通過ecx傳遞,其它引數通過棧傳遞,引數壓棧順序為
從右到左,由被呼叫的函式平衡棧:
class test
virtual ~test()
virtual int run(void *a, void *b, void *c, void *d, void *e)
};class subtest:
public test
virtual ~subtest()
virtual int run(void *a, void *b, void *c, void *d, void *e)
};
與subtest.run(0,0,0,0,0)對應的呼叫彙編**為:
push 0 ; e
push 0 ; d
push 0 ; c
push 0 ; b
push 0 ; a
lea ecx, [ebp+s] ; this
call ?run@subtest@@uaehpax0000@z ; subtest::run(void *,void *,void *,void *,void *)
函式呼叫約定
函式呼叫約定有多種,這裡簡單說一下 1 stdcall 呼叫約定相當於16位動態庫中經常使用的 pascal 呼叫約定。在32位的vc 5.0中pascal呼叫約定不再被支援 實際上它已被定義為 stdcall。除了 pascal外,fortran和 syscall也不被支援 取而代之的是 stdc...
函式呼叫約定
函式呼叫約定1.stdcall是pascal程式的預設呼叫方式,通常用於win32 api中,函式採用從右到左的壓棧方式,自己在退出時清空堆疊。vc將函式編譯後會在函式名前面加上下劃線字首,在函式名後加上 和引數的位元組數。2 c呼叫約定 即用 cdecl關鍵字說明 按從右至左的順序壓引數入棧,由呼...
函式呼叫約定
1.stdcall是pascal程式的預設呼叫方式,通常用於win32 api中,函式採用從右到左的壓棧方式,自己在退出時清空堆疊。vc將函式編譯後會在函式名前面加上下劃線字首,在函式名後加上 和引數的位元組數。2 c呼叫約定 即用 cdecl關鍵字說明 按從右至左的順序壓引數入棧,由呼叫者把引數彈...