;int __stdcall Add(int a, int b)
push ebp
mov ebp,esp
sub esp,40h
push ebx
push esi
push edi
lea edi,[ebp-40h]
mov ecx,10h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
;return (a + b);
mov eax,dword ptr [ebp+8]
add eax,dword ptr [ebp+0Ch]
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 8 ;清棧
3、__fastcall
__fastcall約定用於對效能要求非常高的場合。__fastcall約定將函數的從左邊開始的兩個大小不大於4個位元組(DWORD)的參數分別放在ECX和EDX寄存器,其餘的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的堆棧。__fastcall可以寫成_fastcall。
依舊是相類似的例子,此時函數呼叫慣例為__fastcall,函數參數個數增加2個:
int __fastcall Add(int a, double b, int c, int d)
{
return (a + b + c + d);
}
; int __fastcall Add(int a, double b, int c, int d)
push ebp
mov ebp,esp
sub esp,48h
push ebx
push esi
push edi
push ecx
lea edi,[ebp-48h]
mov ecx,12h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
pop ecx
mov dword ptr [ebp-8],edx
mov dword ptr [ebp-4],ecx
;return (a + b + c + d);
fild dword ptr [ebp-4]
fadd qword ptr [ebp+8]
fiadd dword ptr [ebp-8]
fiadd dword ptr [ebp+10h]
call __ftol (004011b8)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 0Ch ;清棧
在VC++中,函數修飾名由編譯類型(C或C++)、函數名、類名、呼叫慣例、傳回型別、參數等多種因素共同決定。下面分C編譯、C++編譯(非類成員函數)和C++類及其成員函數編譯三種情況說明:
1、C編譯時間函數名稱修飾
當函數使用__cdecl呼叫慣例時,編譯器僅在原函數名前加上一個底線首碼,格式為_functionname。例如:函數int __cdecl Add(int a, int b),輸出後為:_Add。
當函數使用__stdcall呼叫慣例時,編譯器在原函數名前加上一個底線首碼,後面加上一個@符號和函數參數的位元組數,格式為_functionname@number。例如:函數int __stdcall Add(int a, int b),輸出後為:_Add@8。
當函數是用__fastcall呼叫慣例時,編譯器在原函數名前加上一個@符號,後面是加一個@符號和函數參數的位元組數,格式為@functionname@number。例如:函數int __fastcall Add(int a, int b),輸出後為:@Add@8。