_stdcall _fastcall _cdecl的反汇编区别

本文深入探讨了C语言中三种不同的调用约定:cdecl、stdcall和fastcall的特点及区别。通过具体的代码实例,详细分析了每种调用约定下参数传递的方式、堆栈平衡的策略以及如何判断函数参数的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "stdafx.h"
  int _cdecl test1(int a,int b,int c)
  {
	  return a+b;
  }

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

  int _fastcall test3(int a,int b,int c)
  {
	  return a+b;
  }
int _tmain(_In_ int _Argc,char* _In_reads_)
{	
	
	test1(1,2,3);
	test2(1,2,3);
	test3(1,2,3);
	getchar();
	return 0;
}

进入反汇编查看 _cdecl 特点

	test1(1,2,3);
002414DE 6A 03                        push        3    //自右向左压入参数
002414E0 6A 02                        push        2  
002414E2 6A 01                        push        1  
002414E4 E8 E3 FC FF FF               call        test1 (02411CCh)  
002414E9 83 C4 0C                     add         esp,0Ch      //在函数返回后平衡堆栈 

_cdecl 是外平栈 自右向左压入参数

_stdcall的特点

	test2(1,2,3);
002414EC 6A 03                push        3  
002414EE 6A 02                push        2  
002414F0 6A 01                push        1  
002414F2 E8 9A FB FF FF       call        test2 (0241091h)  

进入 call        test2 (0241091h)  

0241430 55                    push        ebp  
00241431 8B EC                mov         ebp,esp  
00241433 81 EC C0 00 00 00    sub         esp,0C0h  
00241439 53                   push        ebx  
0024143A 56                   push        esi  
0024143B 57                   push        edi  
0024143C 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
00241442 B9 30 00 00 00       mov         ecx,30h  
00241447 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0024144C F3 AB                rep stos    dword ptr es:[edi]  
    12: 	  return a+b;
0024144E 8B 45 08             mov         eax,dword ptr [a]  
    12: 	  return a+b;
00241451 03 45 0C             add         eax,dword ptr [b]  
    13:   }
00241454 5F                   pop         edi  
00241455 5E                   pop         esi  
00241456 5B                   pop         ebx  
00241457 8B E5                mov         esp,ebp  
00241459 5D                   pop         ebp  
0024145A C2 0C 00             ret         0Ch     //在这里平栈

_stdcall的特点 参数自右向左压入栈内 内平衡堆栈

_fastcall的特点

002414F7 6A 03                push        3  
002414F9 BA 02 00 00 00       mov         edx,2  //使用了两个寄存器压入参数
002414FE B9 01 00 00 00       mov         ecx,1  
00241503 E8 6F FC FF FF       call        test3 (0241177h)  

进入  call        test3 (0241177h)  


00241470 55                   push        ebp  
00241471 8B EC                mov         ebp,esp  
00241473 81 EC D8 00 00 00    sub         esp,0D8h  
00241479 53                   push        ebx  
0024147A 56                   push        esi  
0024147B 57                   push        edi  
0024147C 51                   push        ecx  
0024147D 8D BD 28 FF FF FF    lea         edi,[ebp-0D8h]  
00241483 B9 36 00 00 00       mov         ecx,36h  
00241488 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0024148D F3 AB                rep stos    dword ptr es:[edi]  
0024148F 59                   pop         ecx  //这里使用ecx传进来的值
00241490 89 55 EC             mov         dword ptr [b],edx  
00241493 89 4D F8             mov         dword ptr [a],ecx  
    17: 	  return a+b;
00241496 8B 45 F8             mov         eax,dword ptr [a]  
00241499 03 45 EC             add         eax,dword ptr [b]  
    18:   }
0024149C 5F                   pop         edi  
0024149D 5E                   pop         esi  
0024149E 5B                   pop         ebx  
0024149F 8B E5                mov         esp,ebp  
002414A1 5D                   pop         ebp  
002414A2 C2 04 00             ret         4    //这里平衡堆栈只有4个字节  另外两个参数使用的寄存器不需要平衡

_fastcall的特点 参数自右向左压入堆栈 使用内平栈 当参数少于3个时,使用了两个寄存器直接传值

对比三种调用约定的特点 当发现是外平栈的时候,可以用 add esp,0Ch 这一句判断函数参数的个数为3个

_stdcall _fastcall 这两种调用约定的函数参数个数判断则要看是否使用了寄存器传参数,在函数里面看有没有寄存器是直接使用的 然后加上ret的值 就可以判断函数的参数个数

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值