温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎样进行C++调用

发布时间:2021-10-27 17:40:08 来源:亿速云 阅读:252 作者:柒染 栏目:编程语言

本篇文章给大家分享的是有关怎样进行C++调用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

进行C++调用时遇到了棘手的问题,Naked Call这是一个很少见的C++调用约定,建议程序设计者不要使用。编译器不会给这种函数增加初始化和清理代码,省的变成了白用工。

调用处push 1push 2call functionadd esp,8 注意:这里C++调用者在恢复堆栈被调用函数_function处push ebp 保存ebp寄存器,该寄存器将用来保存堆栈的栈顶指针,可以在函数退出时恢复mov ebp,esp 保存堆栈指针mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向aadd eax,[ebp + 0CH] 堆栈中ebp + 12处保存了bmov esp,ebp 恢复esppop ebpret 注意,这里没有修改堆栈

MSDN中说,该修饰自动在函数名前加前导的下划线,因此函数名在符号表中被记录为_function,但是我在编译时似乎没有看到这种变化。由于参数按照从右向左顺序压栈,因此最开始的参数在最接近栈顶的位置,因此当采用不定个数参数时,***个参数在栈中的位置肯定能知道,只要不定的参数个数能够根据***个后者后续的明确的参数确定下来,就可以使用不定参数,例如对于CRT中的sprintf函数,定义为:

class A{public:   int function1(int a,int b);     int function2(int a,...);};  int A::function1 (int a,int b){     return a+b;  }#include int A::function2(int a,...)  {   va_list ap;     va_start(ap,a);     int i;     int result = 0;     for(i = 0 ; i < a ; i ++)     {       result += va_arg(ap,int);   }

函数的***个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈被调用函数清理堆栈函数名修改规则同这是一个很少见的调用约定,一般程序设计者建议不要使用。

编译器不会给这种函数增加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回结果。这一般用于实模式驱动程序设计,假设定义一个求和的加法程序,可以定义为:

__declspec(naked) int add(int a,int b){ __asm mov eax,a __asm add eax,b __asm ret }

注意,这个函数没有显式的return返回值,返回通过修改eax寄存器实现,而且连退出函数的ret指令都必须显式插入。上面代码被翻译成汇编以后变成:

declspec(naked) int add(int a,int b){ __asm mov eax,a __asm add eax,b __asm ret }

由于调用者没有理解WINAPI的含义错误的增加了这个修饰,上述代码必然导致堆栈被破坏,MFC在编译时插入的checkesp函数将告诉你,堆栈被破坏了。

以上就是怎样进行C++调用,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++
AI