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


    32位下_stdcall, _fastcall, _cdecl

    #include <windows.h>
    
    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 <windows.h>
    
    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不需要传对象,其他都一样.
  • 相关阅读:
    OC面向对象—封装
    OC内存管理
    OC方法和文件编译
    OC语言基础知识
    OC语言前期准备
    C语言指针基础
    C语言字符串
    C语言数组
    C语言内存分析
    C语言函数
  • 原文地址:https://www.cnblogs.com/cqubsj/p/6201529.html
Copyright © 2020-2023  润新知