[转][转]__cdecl,__fastcall, __stdcall 什么区别

挂钩__usercall函数型 知道人说起过挂钩__usercall函数型?我挂钩__thiscall,__stdcall和__cdecl电话,但这就足够了 认识任何人挂钩库__usercall's或如何挂钩这种类型的翻译对__stdcall或__cdecl? 函数谁我必须挂钩起先是: int __usercall func(int a, int b, int c, unsigned int d, signed int e); 阅读详情
__cdecl,__fastcall,  __stdcall  什么区别?
---------------------------------------------------------------  
 
函数参数入栈的方式  
---------------------------------------------------------------  
 
在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式。  
比如说__cdecl,它是标准的c方法的堆栈调用方式,就是在函数调用时的参数压入堆栈是与函数的声明顺序相反的,其它两个可以看MSDN,不过这个对我们编程没有太大的作用  
---------------------------------------------------------------  
 
调用约定    
 
调用约定(Calling  convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。MFC支持以下调用约定:  
 
_cdecl    
 
按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。  
 
如函数void  test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是?test@@ZAXXZ。  
 
这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。  
 
_stdcall    
 
按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int  func(int  a,  double  b)的修饰名是_func@12。对于“C++”函数,则有所不同。  
 
所有的Win32  API函数都遵循该约定。  
 
 
_fastcall    
 
头两个DWORD类型或者占更少字节的参数被放入ECX和EDX寄存器,其他剩下的参数按从右到左的顺序压入栈。由被调用者把参数弹出栈,对于“C”函数或者变量,修饰名以“@”为前缀,然后是函数名,接着是符号“@”及参数的字节数,如函数int  func(int  a,  double  b)的修饰名是@func@12。对于“C++”函数,有所不同。  
 
未来的编译器可能使用不同的寄存器来存放参数。  
 
 
thiscall    
 
仅仅应用于“C++”成员函数。this指针存放于CX寄存器,参数从右到左压栈。thiscall不是关键词,因此不能被程序员指定。  
 
 
naked  call    
 
采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked  call不产生这样的代码。  
 
naked  call不是类型修饰符,故必须和_declspec共同使用,如下:  
 
__declspec(  naked  )  int  func(  formal_parameters  )  
 
{  
 
//  Function  body  
 
}  
 
 
过时的调用约定    
 
原来的一些调用约定可以不再使用。它们被定义成调用约定_stdcall或者_cdecl。例如:  
 
#define  CALLBACK  __stdcall  
 
#define  WINAPI  __stdcall  
 
#define  WINAPIV  __cdecl  
 
#define  APIENTRY  WINAPI  
 
#define  APIPRIVATE  __stdcall  
 
#define  PASCAL  __stdcall  
函数的调用约定(cdeclstdcallfastcall,...) 调用约定   调用约定阐释了程序中函数的调用方式。当一个调用约定形成,我们需要讨论的是被调用的函数是如何获取数据(例如参数),以及这些数据在堆栈中是如何存放的。对于逆向工程来说,深入了解调用约定是很有必要的。因为在逆向工程中会经常遇见不同的调用约定。而且,确定一个函数的调用约定在逆向工程中对于你理解函数也有比较好的帮助。   在我们讨论不同的调用约定之前,先了解一些基础的函数调用指令:CALL 阅读详情

相关推荐

C语言函数参数入栈顺序

C语言函数参数入栈顺序从右到bai左是为了方便可变参数du函数。 一、在函数调用时,函数参数的传递,在C语言中是通过栈数据结构实现的。 在调用函数时,先根据调用函数使用的参数,自右向左依次压入栈中,然后调用函数,在函数开始执行时,将参数再依次弹栈。根据栈数据结构先进后出的特点,在函数中弹栈的顺序就是从左向右的。 二、对于参数固定的函数,无论是从左向右还是从右向左,都没什么区别,最终都是所有参数全部传递。 三、对于可变参数,比如printf,会在第一个参数格式字符串中,指明后续有几个参数,各自是什么类型的。于

jianmai3616的博客 6293

【C/C++】总结常用的函数调用约定

 一、函数调用的基本步骤 函数调用大致包括以下几个步骤。(1)参数入栈:将参数从右向左依次压入系统栈中。(2)返回地址入栈:将当前代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行。(3)代码区跳:处理器从当前代码区跳到被调用函数的入口处。(4)栈帧调整:具体包括:保存当前栈帧状态值,已备后面恢复本栈帧时使用(EBP入栈)。将当前栈帧切换到新栈帧(

guansir的专栏 1711

函数参数入栈解析

栈:用于维护函数调用的上下文,通常在用户空间的最高地址处分配,增长方向向低地址增长。在i386下,栈顶由esp寄存器进行定位,压栈的操作使栈顶的地址减小,即esp减小;弹出的操作使栈顶地址增大,即esp增大。 栈保存了函数调用所需要的维护信息,这被称为堆栈帧(Stack Frame)或活动记录(Active Record),其包括如下内容: 函数的返回地址和参数 临时变量:包括函数的非静态局部变...

会飞的鱼的博客 5650

__stdcall,__cdecl,__fastcall,_stdcall,_cdecl,_fastcall 区别简介[]

今天写线程函数时,发现msdn中对ThreadProc的定义有要求: DWORD WINAPI ThreadProc(LPVOID lpParameter); 不解为什么要用WINAPI宏定义,查了后发现下面的定义。于是乎需要区别__stdcall和__cdecl两者的区别; #define CALLBACK __stdcall #define WINAPI __st...

weixin_30268921的博客 93

__stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介(

 __stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介 1.今天写线程函数时,发现msdn中对ThreadProc的定义有要求:DWORD WINAPI ThreadProc(LPVOID lpParameter); 不解为什么要用WINAPI宏定义,查了后发现下面的定义。于是乎需要区别__stdcall和__cd

嘎布拉 530

cdeclstdcallfastcall、thiscall函数调用约定区别

 在C语言中,假设我们有这样的一个函数:    int function(int a,int b)    调用时只要用result = function(1,2)这样的方式就可以使用这个函数。但是,当高级语言被编译成计算机可以识别的机器码时,有一个问题就凸现出来:在CPU中,计算机没有办法知道一个函数调用需要多少个、什么样的参数,也没有硬件可以保存这些参数。也就是说,计算机不知道怎么给这...

JONE_CHen2016的博客 533

cdeclstdcallfastcall、declspec 的用法和区别()

首先这三个修饰符是c和c++调用约定 调用约定(Calling convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。MFC支持以下调用约定:      __cdecl,__stdcal和__fastcalll都是函数调用规范,规定了参数出入栈的顺序和方法,如果只用VC编程的话可以不用关心,但是要在C++和Pascal等其他语言通

在水一方 775

cdeclstdcallfastcall函数调用约定区别

507

】调用约定__cdecl、__stdcall和__fastcall区别

什么是调用约定 函数的调用约定,顾名思义就是对函数调用的一个约束和规定(规范),描述了函数参数是怎么传递和由谁清除堆栈的。它决定以下内容:(1)函数参数的压栈顺序,(2)由调用者还是被调用者把参数弹出栈,(3)以及产生函数修饰名的方法。 历史背景 在微机出现之前,计算机厂商几乎都会提供一份操作系统和为不同编程语言编写的编译器。平台所使用的调用约定都是由厂商的软件实现定义的。 在Apple Ⅱ出现之前的早期微机几乎都是“裸机”,少有一份OS或编译器的,即是IBM PC也是如此。IBM PC兼容机的唯

sinolover的专栏 879

cdeclstdcallfastcall函数调用约定区别(

在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就可以使用这个函数。但是,当高级语言被编译成计算机可以识别的机器码时,有一个问题就凸现出来:在CPU中,计算机没有办法知道一个函数调用需要多少个、什么样的参数,也没有硬件可以保存这些参数。也就是说,...

weixin_33757911的博客 140

调用约定__cdecl、__stdcall和__fastcall区别

什么是调用约定 函数的调用约定,顾名思义就是对函数调用的一个约束和规定(规范),描述了函数参数是怎么传递和由谁清除堆栈的。它决定以下内容:(1)函数参数的压栈顺序,(2)由调用者还是被调用者把参数弹出栈,(3)以及产生函数修饰名的方法。 历史背景 在微机出现之前,计算机厂商几乎都会提供一份操作系统和为不同编程语言编写的编译器。平台所使用的调用约定都是由厂商的软件实现定义的。 在Apple...

a3192048的博客 1万+

MemorySharp 调用约定详解:CdeclStdcallFastcall、Thiscall 如何选择?

MemorySharp 是一个基于 C# 的 Windows 内存编辑库,它最强大的功能之一就是能把汇编代码注入远程进程并直接调用目标函数。而**调用约定**(Calling Convention)正是决定这些函数调用能否成功的关键。对新手来说,CdeclStdcallFastcall、Thiscall 这四兄弟常常让人一头雾水——选错了,轻则崩溃蓝屏,重则直接让目标程序闪退。本文将用最通俗的

gitblog_00562的博客 715
上一篇: [转][转]RS-232-C串行端口监控软件的程序实现
下一篇: C++资源之不完全导引
zeroless
博客等级 码龄22年 11粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值