各种函数调用约定及浮点数传参

32位下_stdcall, _fastcall, _cdecl

#include 

int _stdcall Func1(int a, int b, int c, int d)
{
    return a+b+c+d;
}
int _fastcall Func2(int a, int b, int c, int d)   
{
    return a+b+c+d;
}
int _cdecl Func3(int a, int b, int c, int d)
{
    return a + b + c + d;
}

double _stdcall Func4(double a, double b, double c, double d)
{
    return a + b + c + d;
}

double _fastcall Func5(double a, double b, double c, double d)
{
    return a + b + c + d;
}

double _cdecl Func6(double a, double b, double c, double d)
{
    return a + b + c + d;
}

int _stdcall Func7(int a, double b, int c, double d)
{
    return a + b + c + d;
}

int _fastcall Func8(int a, double b, int c, double d)
{
    return a + b + c + d;
}

int _cdecl Func9(int a, double b, int c, double d)
{
    return a + b + c + d;
}

int pascal Func10(int a, int b, int c, int d)   //似乎#define pascal __stdcall  不过pascal也太古老了
{
    return a + b + c + d;
}

int main()
{
    Func1(1,2,3,4);
    Func2(5,6,7,8);
    Func3(2,2,3,4);

    Func4(1.0, 2.0, 3.0, 4.0);
    Func5(1.0, 2.0, 3.0, 4.0);
    Func6(1.0, 2.0, 3.0, 4.0);

    Func7(1, 2.0, 3, 4.0);
    Func8(1, 2.0, 3, 4.0);
    Func9(1, 2.0, 3, 4.0);

    Func10(1, 2, 3, 4);

    return 0;
}
/*
0101178E 6A 04                push        4
01011790 6A 03                push        3
01011792 6A 02                push        2
01011794 6A 01                push        1
01011796 E8 BF F8 FF FF       call        Func1 (0101105Ah)
0101179B 6A 08                push        8
0101179D 6A 07                push        7
0101179F BA 06 00 00 00       mov         edx,6
010117A4 B9 05 00 00 00       mov         ecx,5
010117A9 E8 57 F8 FF FF       call        Func2 (01011005h)
010117AE 6A 04                push        4
010117B0 6A 03                push        3
010117B2 6A 02                push        2
010117B4 6A 02                push        2
010117B6 E8 E3 FA FF FF       call        Func3 (0101129Eh)
010117BB 83 C4 10             add         esp,10h */


/*   Func4
         sub         esp,8
00F64221 movsd       xmm0,mmword ptr [__real@4010000000000000 (0F66BE8h)]
00F64229 movsd       mmword ptr [esp],xmm0
00F6422E sub         esp,8
00F64231 movsd       xmm0,mmword ptr [__real@4008000000000000 (0F66BE0h)]
00F64239 movsd       mmword ptr [esp],xmm0
00F6423E sub         esp,8
00F64241 movsd       xmm0,mmword ptr [__real@4000000000000000 (0F66BD8h)]
00F64249 movsd       mmword ptr [esp],xmm0
00F6424E sub         esp,8
00F64251 movsd       xmm0,mmword ptr [__real@3ff0000000000000 (0F66BD0h)]
00F64259 movsd       mmword ptr [esp],xmm0
00F6425E call        Func4 (0F6134Dh)
00F64263 fstp        st(0)  */

/*  Func5  

011F4D55 83 EC 08             sub         esp,8
011F4D58 F2 0F 10 05 E8 6B 1F 01 movsd       xmm0,mmword ptr [__real@4010000000000000 (011F6BE8h)]
011F4D60 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
011F4D65 83 EC 08             sub         esp,8
011F4D68 F2 0F 10 05 E0 6B 1F 01 movsd       xmm0,mmword ptr [__real@4008000000000000 (011F6BE0h)]
011F4D70 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
011F4D75 83 EC 08             sub         esp,8
011F4D78 F2 0F 10 05 D8 6B 1F 01 movsd       xmm0,mmword ptr [__real@4000000000000000 (011F6BD8h)]
011F4D80 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
011F4D85 83 EC 08             sub         esp,8
011F4D88 F2 0F 10 05 D0 6B 1F 01 movsd       xmm0,mmword ptr [__real@3ff0000000000000 (011F6BD0h)]
011F4D90 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
011F4D95 E8 B8 C5 FF FF       call        Func5 (011F1352h)
011F4D9A DD D8                fstp        st(0)  */

/* Func6

01214DEC 83 EC 08             sub         esp,8
01214DEF F2 0F 10 05 E8 6B 21 01 movsd       xmm0,mmword ptr [__real@4010000000000000 (01216BE8h)]
01214DF7 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
01214DFC 83 EC 08             sub         esp,8
01214DFF F2 0F 10 05 E0 6B 21 01 movsd       xmm0,mmword ptr [__real@4008000000000000 (01216BE0h)]
01214E07 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
01214E0C 83 EC 08             sub         esp,8
01214E0F F2 0F 10 05 D8 6B 21 01 movsd       xmm0,mmword ptr [__real@4000000000000000 (01216BD8h)]
01214E17 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
01214E1C 83 EC 08             sub         esp,8
01214E1F F2 0F 10 05 D0 6B 21 01 movsd       xmm0,mmword ptr [__real@3ff0000000000000 (01216BD0h)]
01214E27 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0
01214E2C E8 26 C5 FF FF       call        Func6 (01211357h)
01214E31 DD D8                fstp        st(0)
01214E33 83 C4 20             add         esp,20h  */


//结果发现浮点型的参数全部都是弄到栈里传参的

/*  Func7

01234E86 sub         esp,8
01234E89 movsd       xmm0,mmword ptr [__real@4010000000000000 (01236BE8h)]
01234E91 movsd       mmword ptr [esp],xmm0
01234E96 push        3
01234E98 sub         esp,8
01234E9B movsd       xmm0,mmword ptr [__real@4000000000000000 (01236BD8h)]
01234EA3 movsd       mmword ptr [esp],xmm0
01234EA8 push        1
01234EAA call        Func7 (0123135Ch)  */

/*  Func8

00834EFF sub         esp,8
00834F02 movsd       xmm0,mmword ptr [__real@4010000000000000 (0836BE8h)]
00834F0A movsd       mmword ptr [esp],xmm0
00834F0F sub         esp,8
00834F12 movsd       xmm0,mmword ptr [__real@4000000000000000 (0836BD8h)]
00834F1A movsd       mmword ptr [esp],xmm0
00834F1F mov         edx,3
00834F24 mov         ecx,1
00834F29 call        Func8 (0831361h)  */     //大发现


/*  Func9

00834F2E  sub         esp,8
00834F31  movsd       xmm0,mmword ptr [__real@4010000000000000 (0836BE8h)]
00834F39  movsd       mmword ptr [esp],xmm0
00834F3E  push        3
00834F40  sub         esp,8
00834F43  movsd       xmm0,mmword ptr [__real@4000000000000000 (0836BD8h)]
00834F4B  movsd       mmword ptr [esp],xmm0
00834F50  push        1
00834F52  call        Func9 (0831366h)
00834F57  add         esp,18h  */

64位下,没什么约定

#include 

int Func1(int a, int b, int c, int d)
{
    return a + b + c + d;
}

double Func2(double a, double b, double c, double d)
{
    return a + b + c + d;
}

int Func3(int a, double b, int c, double d)
{
    return a + b + c + d;
}

int Func4(int a, int b, int c, int d, int e, int f)
{
    return a + b + c + d + e + f;
}

int Func5(int a, int b, int c, int d, double e, double f)
{
    return a + b + c + d + e + f;
}

int Func6(int a, int b, int c, int d, double e, int f, double g, int h)
{
    return a + b + c + d + e + f + g + h;
}

int main()
{
    int a = Func1(1, 2, 3, 4);
    double b = Func2(1.0, 2.0, 3.0, 4.0);
    int c = Func3(1, 2.0, 3, 4.0);
    int d = Func4(1, 2, 3, 4, 5, 6);
    int e = Func5(1, 2, 3, 4, 5.0, 6.0);
    int f = Func6(1, 2, 3, 4, 5.0, 6, 7.0, 8);
    return 0;
}

/*Func1
00007FF7AF04170E  mov         r9d,4
00007FF7AF041714  mov         r8d,3
00007FF7AF04171A  mov         edx,2
00007FF7AF04171F  mov         ecx,1
00007FF7AF041724  call        Func1 (07FF7AF0410B9h)
00007FF7AF041729  mov         dword ptr [a],eax  
*/

/*Func2
00007FF7F7723C7C  movsd       xmm3,mmword ptr [__real@4010000000000000 (07FF7F7729C88h)]
00007FF7F7723C84  movsd       xmm2,mmword ptr [__real@4008000000000000 (07FF7F7729C50h)]
00007FF7F7723C8C  movsd       xmm1,mmword ptr [__real@4000000000000000 (07FF7F7729C30h)]
00007FF7F7723C94  movsd       xmm0,mmword ptr [__real@3ff0000000000000 (07FF7F7729BD8h)]
00007FF7F7723C9C  call        Func2 (07FF7F7721343h)
00007FF7F7723CA1  movsd       mmword ptr [b],xmm0  
*/

/*Func3
                  movsd       xmm3,mmword ptr [__real@4010000000000000 (07FF7103D9C30h)]
00007FF7103D3624  mov         r8d,3
00007FF7103D362A  movsd       xmm1,mmword ptr [__real@4000000000000000 (07FF7103D9BD8h)]
00007FF7103D3632  mov         ecx,1
00007FF7103D3637  call        Func3 (07FF7103D133Eh)  

  浮点参数和整型参数是一起计数的
  意味着每列中,只能取一个

  rcx  rdx  r8   r9
  xmm0 xmm1 xmm2 xmm3           

*/ 

/*Func4 00007FF6F96848C9 mov dword ptr [rsp+28h],6 00007FF6F96848D1 mov dword ptr [rsp+20h],5 00007FF6F96848D9 mov r9d,4 00007FF6F96848DF mov r8d,3 00007FF6F96848E5 mov edx,2 00007FF6F96848EA mov ecx,1 00007FF6F96848EF call Func4 (07FF6F968134Dh) 00007FF6F96848F4 mov dword ptr [d],eax */ /*Func5 00007FF7364E5307 movsd xmm0,mmword ptr [__real@4018000000000000 (07FF7364E9D78h)] 00007FF7364E530F movsd mmword ptr [rsp+28h],xmm0 00007FF7364E5315 movsd xmm0,mmword ptr [__real@4014000000000000 (07FF7364E9CB0h)] 00007FF7364E531D movsd mmword ptr [rsp+20h],xmm0 00007FF7364E5323 mov r9d,4 00007FF7364E5329 mov r8d,3 00007FF7364E532F mov edx,2 00007FF7364E5334 mov ecx,1 00007FF7364E5339 call Func5 (07FF7364E1352h) 00007FF7364E533E mov dword ptr [e],eax */ /*Func6 00007FF7519C53D4 mov dword ptr [rsp+38h],8 00007FF7519C53DC movsd xmm0,mmword ptr [__real@401c000000000000 (07FF7519C9D80h)] 00007FF7519C53E4 movsd mmword ptr [rsp+30h],xmm0 00007FF7519C53EA mov dword ptr [rsp+28h],6 00007FF7519C53F2 movsd xmm0,mmword ptr [__real@4014000000000000 (07FF7519C9CB0h)] 00007FF7519C53FA movsd mmword ptr [rsp+20h],xmm0 00007FF7519C5400 mov r9d,4 00007FF7519C5406 mov r8d,3 00007FF7519C540C mov edx,2 00007FF7519C5411 mov ecx,1 00007FF7519C5416 call Func6 (07FF7519C1357h) 00007FF7519C541B mov dword ptr [f],eax */ //这样应该是全部的情况了

 补充,类成员函数

class thiscall
{
public:
    static int test(int a, int b, int c, int d)
    {
        return a + b + c + d;
    }

    int test2(int a, int b, int c, int d)
    {
        return a + b + c + d;
    }

    int _stdcall test3(int a, int b, int c, int d)
    {
        return a + b + c + d;
    }

    int _cdecl test4(int a, int b, int c, int d)
    {
        return a + b + c + d;
    }
};

int main()
{
    thiscall obj; 
    int a = thiscall::test(1, 2, 3, 4);
    int b = obj.test2(2, 3, 4, 5);
    int c = obj.test3(3, 4, 5, 6);
    int d = obj.test4(5, 6, 7, 8);

    return 0;
}

//test的
//008D1748  push        4
//008D174A  push        3
//008D174C  push        2
//008D174E  push        1
//008D1750  call        thiscall::test(08D1226h)          这似乎是 _cdecl 不是_stdcall ,后者是callee来平衡堆栈的
//008D1755  add         esp, 10h                          

//test2的
//008D175B  push        5
//008D175D  push        4
//008D175F  push        3
//008D1761  push        2
//008D1763  lea         ecx, [obj]
//008D1766  call        thiscall::test2(08D1082h)

//test3的
//00AE464E  push        6
//00AE4650  push        5
//00AE4652  push        4
//00AE4654  push        3
//00AE4656  lea         eax, [obj]
//00AE4659  push        eax
//00AE465A  call        thiscall::test3(0AE1348h)

//test4的

//003A4D12  push        8
//003A4D14  push        7
//003A4D16  push        6
//003A4D18  push        5
//003A4D1A  lea         eax, [obj]
//003A4D1D  push        eax
//003A4D1E  call        thiscall::test4(03A134Dh)
//003A4D23  add         esp, 14h


//x64下

//test
//00007FF6280918DF  mov         r9d, 4
//00007FF6280918E5  mov         r8d, 3
//00007FF6280918EB  mov         edx, 2
//00007FF6280918F0  mov         ecx, 1
//00007FF6280918F5  call        thiscall::test(07FF628091221h)
//00007FF6280918FA  mov         dword ptr[a], eax

//test2
//00007FF6280918FD  mov         dword ptr[rsp + 20h], 5
//00007FF628091905  mov         r9d, 4
//00007FF62809190B  mov         r8d, 3
//00007FF628091911  mov         edx, 2
//00007FF628091916  lea         rcx, [obj]
//00007FF62809191A  call        thiscall::test2(07FF628091339h)
//00007FF62809191F  mov         dword ptr[b], eax

//test3
//00007FF628091922  mov         dword ptr[rsp + 20h], 6
//00007FF62809192A  mov         r9d, 5
//00007FF628091930  mov         r8d, 4
//00007FF628091936  mov         edx, 3
//00007FF62809193B  lea         rcx, [obj]
//00007FF62809193F  call        thiscall::test3(07FF628091087h)
//00007FF628091944  mov         dword ptr[c], eax

//test4
//00007FF628091947  mov         dword ptr[rsp + 20h], 8
//00007FF62809194F  mov         r9d, 7
//00007FF628091955  mov         r8d, 6
//00007FF62809195B  mov         edx, 5
//00007FF628091960  lea         rcx, [obj]
//00007FF628091964  call        thiscall::test4(07FF62809133Eh)
//00007FF628091969  mov         dword ptr[d], eax

//显然各种调用约定都被无视了,static不需要传对象,其他都一样.

 

转载于:https://www.cnblogs.com/cqubsj/p/6201529.html

你可能感兴趣的:(各种函数调用约定及浮点数传参)