call 指令与 retn 指令 首先我们得了解 CALL 和 RETN 指令的作用,才能更好地理解调用规则,这也是先决条件. 实际上,CALL 指令就是先将下一条指令的 EIP 压栈,然后 JMP 跳转到对应的函数的首地址,当执行完函数体后,通过 RETN 指令从堆栈中弹出 EIP,程序就可以继续执行 CALL 的下一条指令. __cdecl 与 __stdcall 调用规则 C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们一起来浅析四种调用规则的原理和它…
关于函数的调用规则(调用约定),大多数时候是不需要了解的,但是如果需要跨语言的编程,比如VC写的dll要delphi调用,则需要了解. microsoft的vc默认的是__cdecl方式,而windows API则是__stdcall,如果用vc开发dll给其他语言用,则应该指定__stdcall方式.堆栈由谁清除这个很重要,如果是要写汇编函数给C调用,一定要小心堆栈的清除工作,如果是__cdecl方式的函数,则函数本身(如果不用汇编写)则不需要关心保存参数的堆栈的清除,但是如果是__stdca…
关于函数的调用规则(调用约定),大多数时候是不需要了解的,但是如果需要跨语言的编程,比如VC写的dll要delphi调用,则需要了解. microsoft的vc默认的是__cdecl方式,而windows API则是__stdcall,如果用vc开发dll给其他语言用,则应该指定__stdcall方式.堆栈由谁清除这个很重要,如果是要写汇编函数给C调用,一定要小心堆栈的清除工作,如果是__cdecl方式的函数,则函数本身(如果不用汇编写)则不需要关心保存参数的堆栈的清除,但是如果是__stdca…
首先讲解一下栈帧的概念: 从逻辑上讲,栈帧就是一个函数执行的环境:函数参数.函数的局部变量.函数执行完后返回到哪里等等. 实现上有硬件方式和软件方式(有些体系不支持硬件栈) 首先应该明白,栈是从高地址向低地址延伸的.每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息.寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址). 注意:EBP指向当前位于系统栈最上边一个栈帧的底部,而不是系统栈的底部.严格说来,“栈帧底部”和“栈底”是不同的概…
参考原文地址:https://www.cnblogs.com/yenyuloong/p/9626658.html C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们一起来浅析四种调用规则的原理和它们各自的异同.通过一段 C 语言代码来引导我们的浅析过程.这里我们编写了三个函数,它们的功能都是返回两个参数的相加结果,只是每个函数都有不一样的调用规则. 用 OllyDBG 查看了编译后代码的“真面目”.代码中有 4 个 CALL,第一个是 printf,我们不关心…
函数调用方式--__thiscall调用方式和__cdecl,__stdcall有什么区别 首先,__thiscall是关于类的一种调用方式,它与其他调用方式的最大区别是:    __thiscall对每个函数都增加了一个类指针参数   class   aa      {      void   bb(int   cc);      };      实际上bb的函数原形是void   bb(aa   &this,   int   cc);      这就是__thiscall的调用方式 其次,我…
调用约定: __cdecl __fastcall与 __stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数的压栈顺序,2)由调用者还是被调用者把参数弹出栈,3)以及产生函数修饰名的方法. 1.__stdcall调用约定:函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈, 2._cdecl是C和C++程序的缺省调用方式.每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大.函数采用…
_cdecl和__stdcall都是函数调用规范(还有一个__fastcall),规定了参数出入栈的 顺序和方法,如果只用VC编程的话可以不用关心,但是要在C++和Pascal等其他语言通信的时候就要注意了,只有用相同的方法才能够调用成功.另外, 像printf这样接受可变个数参数的函数只有用cdecl才能够实现.      __declspec主要是用于说明DLL的引出函数的,在某些情况下用__declspec(dllexport)在DLL中生命引出函数,比用传统的 DEF文件方便一些.在普通…
__cdecl和__stdcall都是函数调用规范(还有一个__fastcall),规定了参数出入栈的顺序和方法,如果只用VC编程的话可以不用关心,但是要在C++和Pascal等其他语言通信的时候就要注意了,只有用相同的方法才能够调用成功.另外,像printf这样接受可变个数参数的函数只有用cdecl才能够实现.     __declspec主要是用于说明DLL的引出函数的,在某些情况下用__declspec(dllexport)在DLL中生命引出函数,比用传统的DEF文件方便一些.在普通程序中…
(一) __cdecl: c declaration C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈.C/C++默认的调用方式,可用于函数参数不确定的情况下. 1. 被调用函数代码及反汇编: int _cdecl fun(int arg){//被调用者 return arg+1; } push ebp mov ebp, esp ¦ ¦ mov esp, ebp pop ebp retn ;被调用者不清除参数 fun endp 2.调用代码及反汇编: int…
1.使用Visual C++ 6.0创建dll 2. 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal) 要点: 1. 如果你的程序中没有涉及可变参数,最好使用__stdcall关键字 2. __cdecl,__stdcall是声明的函数调用协议.主要是传参和弹栈方面的不同.一般c++用的是__cdecl,windows里大都用的是__stdcall(API)__cdecl 是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl…
1.指针的引用 他也是引用,引用是特定内存块的别名 2.变量定义 更准确的说是内存使用约定,并为该约定命名 命名3.指向常变量的指针和常指针 有点拗口,都是指针,但对于所在内存块的使用约定不同.常变量指针只能用于指向常变量,和普通指针不同.常指针所在内存块有固定的数据不可更改. 4.引用类型做参数时,函数不会操作对应内存块的拷贝,而是直接去操作那块内存. 根据引用这个概念的解释,它是对内存块已有约定进行补充,从而形成了一个新版约定,因此在定义新版约定是必须有个老版约定做基础.引用并没有为问题的解…
成员函数指针与高性能的C++委托(上篇) 撰文:Don Clugston 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(closure)"或"委托 (delegate)")在一些语言中已经证明了它宝贵的价值.在Delphi (Object Pascal)中,面向对象的函数指针是Borland可视化组建库(VCL,Visual Component Library)的基础.而在目前,C#使"委托&…
今天在调程序时,C#调用VC 编译的dll出现堆栈不对称,查了一下资料,转载在这里供大家参考. 问题描述:对 PInvoke 函数“xxFunction()”的调用导致堆栈不对称.原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配.请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 问题解决:1.在c#中函数声明处改一个参数,[DllImport("xx.dll", EntryPoint=“xxFunction”, CallingConvention =…
tkorays(tkorays@hotmail.com) 调用约定(Calling Convention) 是计算机编程中一个比较底层的设计,它主要涉及: 函数参数通过寄存器传递还是栈? 函数参数从左到右还是从右到左压栈? 是否支持可变参数函数(vararg function or variadic function). 是否需要函数原型? 怎么修饰函数名,唯一标识函数? 调用者(caller)还是被调用者(called or callee)清理堆栈? 1. Calling Convention…
下载实例源代码 - 18.5 Kb 下载开发包库文件 - 18.6 Kb 概要 很遗憾, C++ 标准中没能提供面向对象的函数指针. 面向对象的函数指针也被称为闭包(closures) 或委托(delegates), 在类似的语言中已经体现出了它的价值. 在 Delphi(Object Pascal) 中, 他们是 VCL (Borland's Visual Component Library, 宝蓝可视化组件) 的基础. 最近的 C# 让委托的概念更为流行, 这也成为 C# 成功的因素之一.…
1 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做“闭包(closure)”或“委托(delegate)”)在一些语言中已经证明了它宝贵的价值.在Delphi (Object Pascal)中,面向对象的函数指针是Borland可视化组建库(VCL,Visual Component Library)的基础.而在目前,C#使“委托”的概念日趋流行,这也正显示出C#这种语言的成功.在很多应用程序中,“委托”简化了松耦合对象的设计模式[GoF].…
使用 GetProcAddress Function 时,有以下几点需要特别留意: 1. 第二个参数类型是 LPCSTR,不是 : 2. 用 __declspec(dllexport),按 C 名称修饰(extern "C") 导出的函数名,对于 __stdcall 和 __fastcall 调用约定是相同的:对 __cdecl 是不同的(导出的函数名没有前面的下划线): 3. 即使返回值不是 NULL,也有可能发生错误.当 .def 模块不是连续地从 1 开始编号 ordinal 值…
原文(作者:Don Clugston):Member Function Pointers and the Fastest Possible C++ Delegates 译文(作者:周翔): 成员函数指针与高性能的C++委托(上篇) 成员函数指针与高性能的C++委托(中篇) 成员函数指针与高性能的C++委托(下篇) 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做“闭包(closure)”或“委托(delegate)”)在一些语言中已经证明了它…
C调用C++(C++封装以及C对其调用) 来源 https://blog.csdn.net/wonengguwozai/article/details/89854781 相关知识提点:很经典的extern C解释 编译器: gcc和g++编译器区别 gcc是c语言编译器(也可处理c++);g++是c++编译器 g++对.c和.cpp文件都当c++处理:gcc对.c文件当作c处理,对.cpp当做c++处理 g++编译器在使用时其实调用的是gcc编译器 gcc不能自动链接库文件(.so等),一般用g…
https://en.wikipedia.org/wiki/X86_calling_conventions https://msdn.microsoft.com/en-us/library/984x0h58%28v=vs.71%29.aspx 有个题目是 func(int a,int b){ printf("a = %d, b = %d",a,b); } void main(){ int i =0; func(++i,i++); } 答案是 2,0 理解这个问题的 方法   就是理解,…
1. 今天写线程函数时,发现msdn中对ThreadProc的定义有要求:DWORD WINAPI ThreadProc(LPVOID lpParameter); 不解为什么要用WINAPI宏定义,查了后发现下面的定义.于是乎需要区别__stdcall和__cdecl两者的区别: #define CALLBACK __stdcall #define WINAPI __stdcall #define WINAPIV __cdecl #define APIENTRY WINAPI #define A…
今天写线程函数时,发现msdn中对ThreadProc的定义有要求: DWORD WINAPI ThreadProc(LPVOID lpParameter);   不解为什么要用WINAPI宏定义,查了后发现下面的定义.于是乎需要区别__stdcall和__cdecl两者的区别:  #define CALLBACK __stdcall #define WINAPI __stdcall #define WINAPIV __cdecl #define APIENTRY WINAPI #define…
__stdcall,__cdecl,__fastcall的区别 标签: dll编译器pascalclassimportinitialization 2009-12-09 15:07 10472人阅读 评论(1) 收藏 举报  分类: C/C++(22)  __stdcall,__cdecl,__fastcall的区别 一.三者区别一览表 __stdcall __cdecl __fastcall 参数传递方式 右->左 压栈 右->左 压栈 左边开始的两个不大于4字节(DWORD)的参数分别放在…
__stdcall和__cdecl的区别 __stdcall和__cdecl是两种函数名字修饰.(注意是连续的两个下划线) Windows上 windows上不管是C还是C++,默认使用的都是__stdcall方式. 不论__stdcall还是__cdecl函数参数都是从可向左入栈的,并且由调用者完成入栈操作.对于__stdcall方式被调用者自身在函数返回前清空堆栈:而__cdecl则由调用者维护内存堆栈,所以调用者函数生成的汇编代码比前一种方式长. 由__cdecl约定的函数只能被C/C++…
__stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等. 调用协议常用场合 __stdcall:Windows API默认的函数调用协议. __cdecl:C/C++默认的函数调用协议. __fastcall:适用于对性能要求较高的场合. 函数参数入栈方式 __stdcall:函数参数由右向左入栈. __cdecl:函数参数由右向左入栈. __fastcall:从左开始不大于4字节的参数放入C…
__stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等.如下图所示,可以在IDE环境中设定所有函数默认的调用协议,还可以在函数定义时单独设定本函数的调用协议. 调用协议常用场合 __stdcall:Windows API默认的函数调用协议. __cdecl:C/C++默认的函数调用协议. __fastcall:适用于对性能要求较高的场合. 函数参数入栈方式 __stdcall:函数参数由右向左…
常用的调用约定有stdcall,cdecl,fastcall,thiscall,naked call等,以下将 __stdcall.__cdecl和__fastcall三种函数调用协议加以比较,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等. 注: _stdcall是早期16位系统中使用的调用约定,本质是就是stdcall,现行的主要是__stdcall. 调用协议常用场合 __stdcall:Windows API默认的函数调用协议. __cdecl:C/C…
转自:https://www.cnblogs.com/huhewei/p/6080143.html 一.概述 __stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等. 二.调用协议常用场合  __stdcall:Windows API默认的函数调用协议. __cdecl:C/C++默认的函数调用协议. __fastcall:适用于对性能要求较高的场合. 三. 函数参数入栈方式  __stdca…
x86平台下调用约定 我们都知道x86平台下常用的有三种调用约定,__cdecl.__stdcall.__fastcall.我们分别对这三种调用约定进行分析. __cdecl __cdecl是C/C++的默认调用约定,如果不显示声明调用约定的情况下,就是该调用约定.下面我们来从汇编层次来熟悉这种调用约定. 我写了一个函数,如下: int __cdecl TestCdecl(int a, int b, int c, int d, int e) { return a + b + c + d + e;…