__stdcall的名字修饰约定

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了__stdcall的名字修饰约定相关的知识,希望对你有一定的参考价值。

参考技术A

1、修饰名(Decoration name)
“C”或者“C++”函数在内部(编译和链接)通过修饰名识别。修饰名是编译器在编译函数定义或者原
型时生成的字符串。有些情况下使用函数的修饰名是必要的,如在模块定义文件里头指定输出“C++”重载函数、构造函数、析构函数,又如在汇编代码里调用“C””或“C++”函数等。
修饰名由函数名、类名、调用约定、返回类型、参数等共同决定。
2、名字修饰约定随调用约定和编译种类(C或C++)的不同而变化。函数名修饰约定随编译种类和调用约定
的不同而不同,下面分别说明。
a、C编译时函数名修饰约定规则:
__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数,
格式为_functionname@number。
__cdecl调用约定仅在输出函数名前加上一个下划线前缀,格式为_functionname。
__fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,
格式为@functionname@number。
它们均不改变输出函数名中的字符大小写,这和PASCAL调用约定不同,PASCAL约定输出的函数名无任何修饰且全部大写。
b、C++编译时函数名修饰约定规则:
__stdcall调用约定:
1、以“?”标识函数名的开始,后跟函数名;
2、函数名后面以“@@YG”标识参数表的开始,后跟参数表;
3、参数表以代号表示:
X--void ,
D--char,
E--unsigned char,
F--short,
H--int,
I--unsigned int,
J--long,
K--unsigned long,
M--float,
N--double,
_N--bool,
....
PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代
表一次重复;
4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前

5、参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。
其格式为“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,例如
int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”
void Test2() -----“?Test2@@YGXXZ”
__cdecl调用约定:
规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YA”。
__fastcall调用约定:
规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YI”。
VC++对函数的缺省声明是__cdecl,将只能被C/C++调用.
6 用法举例
BOOL _declspec(dllexport)_stdcall InstallHook()

hkb = SetWindowsHookEx(WH_KEYBOARD,
(HOOKPROC)KeyboardProc,
hins,
0);
return TRUE;

函数调用约定

  1. __stdcall
  2. __fastcall

vc6.0:
int __stdcall/__cdecl/__fastcall add(int x, int y)
{
 return x+y;
}

void main()
{
 add(2,3);
}

 

1.__stdcall:

1:    int __stdcall add(int x, int y)
2:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
3:     return x+y;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   add         eax,dword ptr [ebp+0Ch]
4:    }
0040103E   pop         edi
0040103F   pop         esi
00401040   pop         ebx
00401041   mov         esp,ebp
00401043   pop         ebp
00401044   ret         8
5:
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3);
00401068   push        3
0040106A   push        2
0040106C   call        @ILT+0(add) (00401005)
10:   }
00401071   pop         edi
00401072   pop         esi
00401073   pop         ebx
00401074   add         esp,40h
00401077   cmp         ebp,esp
00401079   call        __chkesp (00401090)
0040107E   mov         esp,ebp
00401080   pop         ebp
00401081   ret

00401005   jmp         add (00401020)

2.__cdecl:

1:    int __cdecl add(int x, int y)
2:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
3:     return x+y;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   add         eax,dword ptr [ebp+0Ch]
4:    }
0040103E   pop         edi
0040103F   pop         esi
00401040   pop         ebx
00401041   mov         esp,ebp
00401043   pop         ebp
00401044   ret
5:
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3);
00401068   push        3
0040106A   push        2
0040106C   call        @ILT+10(add) (0040100f)
00401071   add         esp,8
10:   }
00401074   pop         edi
00401075   pop         esi
00401076   pop         ebx
00401077   add         esp,40h
0040107A   cmp         ebp,esp
0040107C   call        __chkesp (00401090)
00401081   mov         esp,ebp
00401083   pop         ebp
00401084   ret

0040100F   jmp         add (00401020)

3.__fastcall

1:    int __fastcall add(int x, int y)
2:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,48h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   push        ecx
0040102A   lea         edi,[ebp-48h]
0040102D   mov         ecx,12h
00401032   mov         eax,0CCCCCCCCh
00401037   rep stos    dword ptr [edi]
0040103A   mov         dword ptr [ebp-8],edx
0040103D   mov         dword ptr [ebp-4],ecx
3:     return x+y;
00401040   mov         eax,dword ptr [ebp-4]
00401043   add         eax,dword ptr [ebp-8]
4:    }
00401046   pop         edi
00401047   pop         esi
00401048   pop         ebx
00401049   mov         esp,ebp
0040104B   pop         ebp
0040104C   ret
5:
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3);
mov         edx,3
0040106D   00401072   call        @ILT+15(add) (00401014)
10:   }
00401077   pop         edi
00401078   pop         esi
00401079   pop         ebx
0040107A   add         esp,40h
0040107D   cmp         ebp,esp
0040107F   call        __chkesp (00401090)
00401084   mov         esp,ebp
00401086   pop         ebp
00401087   ret

00401014   jmp         add (00401020)
====================================================================================
1:    int __fastcall add(int x, int y, int z)
2:    {
0040D480   push        ebp
0040D481   mov         ebp,esp
0040D483   sub         esp,48h
0040D486   push        ebx
0040D487   push        esi
0040D488   push        edi
0040D489   push        ecx
0040D48A   lea         edi,[ebp-48h]
0040D48D   mov         ecx,12h
0040D492   mov         eax,0CCCCCCCCh
0040D497   rep stos    dword ptr [edi]
0040D499   pop         ecx
0040D49A   mov         dword ptr [ebp-8],edx
0040D49D   mov         dword ptr [ebp-4],ecx
3:     return x+y+z;
0040D4A0   mov         eax,dword ptr [ebp-4]
0040D4A3   add         eax,dword ptr [ebp-8]
0040D4A6   add         eax,dword ptr [ebp+8]
4:    }
0040D4A9   pop         edi
0040D4AA   pop         esi
0040D4AB   pop         ebx
0040D4AC   mov         esp,ebp
0040D4AE   pop         ebp
0040D4AF   ret         4
5:
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3,4);
push        4
0040106A   mov         edx,3
0040106F   mov         ecx,2
00401074   call        @ILT+20(add) (00401019)
10:   }
00401079   pop         edi
0040107A   pop         esi
0040107B   pop         ebx
0040107C   add         esp,40h
0040107F   cmp         ebp,esp
00401081   call        __chkesp (00401090)
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret

00401019   jmp         add (0040d480)


 

以上是关于__stdcall的名字修饰约定的主要内容,如果未能解决你的问题,请参考以下文章

带你玩转Visual Studio——调用约定与(动态)库

qt能修改函数调用协议为stdcall吗

_STDCALL&_CDECL 调用约定

C++函数调用方式 stdcall pascal cdecl 总结

cadel fastcall stdcall

汇编 ? cdecl 函数调用约定,stdcall 函数调用约定