A brief analysis of the difference between s and s and s and s

  • 2020-04-01 21:32:06
  • OfStack

1. The __cdecl
__cdecl C is the abbreviation of Declaration (Declaration, the Declaration), said method of C language function calls by default: all the parameters in turn into the stack from right to left, the caller is responsible for the pressed parameters into the stack, the last and the caller is responsible for the clearing the content of the stack, in general, this is the default calling function of C/C + + rules, MS VC compiler USES the rule is the rule 2. __stdcall
_stdcall, short for StandardCall, is the standard C++ method of calling: all parameters are pushed from right to left, with the caller pushing the parameters and the caller clearing the stack

In addition, the modified names generated by functions with different rules of successive cdecl and successive stdcall are also different. The same thing is that the prefix of the generated function modified names is underlined and the suffix is different. Of course, the biggest difference between the two is the way to restore the stack, which is also the most important.


S: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s:


#include <cstdio>
void __cdecl func(int param1, int param2, int param3) {
  int var1 = param1;
  int var2 = param2;
  int var3 = param3;
  printf("%ldn", long(¶m1));
  printf("%ldn", long(¶m2));
  printf("%ldn", long(¶m3));
  printf("----------------n");
  printf("%ldn", long(&var1));
  printf("%ldn", long(&var2));
  printf("%ldn", long(&var3));
  return ;
}
int main() {
  func(1, 2, 3);
  return 0;
}

Note that the func function is modified with s/s s/s/s s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s.


3:    void __cdecl func(int param1, int param2, int param3) {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,4Ch
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-4Ch]
0040102C   mov         ecx,13h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
4:      int var1 = param1;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   mov         dword ptr [ebp-4],eax           ;  Pay attention to var1 . var2 . var3  The order of the stack! 
5:      int var2 = param2;
0040103E   mov         ecx,dword ptr [ebp+0Ch]
00401041   mov         dword ptr [ebp-8],ecx
6:      int var3 = param3;
00401044   mov         edx,dword ptr [ebp+10h]
00401047   mov         dword ptr [ebp-0Ch],edx
...............................................        ;  omitted printf The code of 
15:     return ;
16:   }
004010BD   pop         edi
004010BE   pop         esi
004010BF   pop         ebx
004010C0   add         esp,4Ch
004010C3   cmp         ebp,esp
004010C5   call        __chkesp (004011d0)
004010CA   mov         esp,ebp
004010CC   pop         ebp
004010CD   ret                                         ;  Here is the  ret , by the caller ( main ) restores the stack, but if so  __stdcall  Words, 
                                                       ;  The recovery stack is here 
*******************************************************************************************************************
18:   int main() {
...............................................       ;  Omitting the code to build the stack 
19:     func(1, 2, 3);
00401118   push        3                              ;  will  param3  The pressure into the stack 
0040111A   push        2                              ;  will  param2  The pressure into the stack 
0040111C   push        1                              ;  will  param1  The pressure into the stack 
0040111E   call        @ILT+5(func) (0040100a)        ; @ILT+5(func)  Is the function func Modifies the name of, and 0040100a Is his address 
00401123   add         esp,0Ch                        ;  Restore stack, __cdecl  Rules are made by the caller (here is main ) restore stack 
20:     return 0;
00401126   xor         eax,eax
21:   }
00401128   pop         edi
00401129   pop         esi
0040112A   pop         ebx
0040112B   add         esp,40h
0040112E   cmp         ebp,esp
00401130   call        __chkesp (004011d0)
00401135   mov         esp,ebp
00401137   pop         ebp
00401138   ret

Results the screenshot

< img border = 0 SRC = "/ / files.jb51.net/file_images/article/201303/201336120030086.png" >
The stack structure in the program is shown as follows:
< img border = 0 SRC = "/ / files.jb51.net/file_images/article/201303/201336120135495.png" >

S: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s: s:


#include <cstdio>
void __stdcall func(int param1, int param2, int param3) {
  int var1 = param1;
  int var2 = param2;
  int var3 = param3;
  printf("%ldn", long(¶m1));
  printf("%ldn", long(¶m2));
  printf("%ldn", long(¶m3));
  printf("----------------n");
  printf("%ldn", long(&var1));
  printf("%ldn", long(&var2));
  printf("%ldn", long(&var3));
  return ;
}
int main() {
  func(1, 2, 3);
  return 0;
}

Note that the func function is modified with s/s s/s/s s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s.


1:    #include <cstdio>
2:
3:    void __stdcall func(int param1, int param2, int param3) {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,4Ch
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-4Ch]
0040102C   mov         ecx,13h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
4:      int var1 = param1;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   mov         dword ptr [ebp-4],eax
5:      int var2 = param2;
0040103E   mov         ecx,dword ptr [ebp+0Ch]
00401041   mov         dword ptr [ebp-8],ecx
6:      int var3 = param3;
00401044   mov         edx,dword ptr [ebp+10h]
00401047   mov         dword ptr [ebp-0Ch],edx
..............................................  ;  omit  printf  code 
15:     return ;
16:   }
004010BD   pop         edi
004010BE   pop         esi
004010BF   pop         ebx
004010C0   add         esp,4Ch
004010C3   cmp         ebp,esp
004010C5   call        __chkesp (004011d0)
004010CA   mov         esp,ebp
004010CC   pop         ebp
004010CD   ret         0Ch                       ; __stdcall  Here the stack is restored, but if it is  __cdecl  So here is  ret,
                                                 ;  The stack is restored by the caller (here is  main ) to be responsible for 
*******************************************************************************************************************
18:   int main() {
...........................................       ;  Omitting the build stack code 
19:     func(1, 2, 3);
00401118   push        3                          ; param3  Onto the stack 
0040111A   push        2                          ; param2  Onto the stack  
0040111C   push        1                          ; param1  Onto the stack  
0040111E   call        @ILT+0(func) (00401005)    ; @ILT+0(func)  Is the modifier of the function, and  00401005  Is to call the function func The address of the 
20:     return 0;
00401123   xor         eax,eax
21:   }
00401125   pop         edi
00401126   pop         esi
00401127   pop         ebx
00401128   add         esp,40h
0040112B   cmp         ebp,esp
0040112D   call        __chkesp (004011d0)
00401132   mov         esp,ebp
00401134   pop         ebp
00401135   ret

The result of operation is the same as that of using the model with the same stack structure. The only difference is that the position of the adjustment stack (restore stack) and the modifier name of the generated function are different. This difference is the most important difference between the model and the model


Related articles: