首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如果C++使用cdecl调用约定,为什么在edi中会显示正在传递的参数?

C++使用cdecl调用约定时,在edi寄存器中显示正在传递的参数是因为cdecl调用约定要求函数的调用者负责清理堆栈上的参数。为了实现这一点,调用者需要将参数按照从右到左的顺序依次压入堆栈,然后调用函数。在函数内部,函数通过edi寄存器来访问堆栈上的参数。

具体来说,当使用cdecl调用约定时,函数的参数会按照从右到左的顺序依次压入堆栈。然后,函数通过edi寄存器来访问堆栈上的参数。在函数内部,可以通过edi+偏移量的方式来访问不同位置的参数。

这种调用约定的优势在于它比较灵活,可以适用于不同类型的函数和参数。它的应用场景包括但不限于需要动态传递参数的函数调用,例如回调函数、可变参数函数等。

腾讯云提供了丰富的云计算产品和服务,其中与C++开发相关的产品包括云服务器CVM、容器服务TKE、函数计算SCF等。您可以通过以下链接了解更多关于腾讯云相关产品的信息:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

ndk C++ 编译器函数名修饰规则

1、__stdcall调用约定:函数参数自右向左通过栈传递,被调用函数返回前清理传送参数内存栈, 2、_cdecl是C和C++程序缺省调用方式。...另一种需要指定函数 名字修饰情况是汇编程序中调用C或C++函数。如果函数名字,调用约定,返回值类型或函数参数有任何改变,原来名字修饰就不再有效,必须指定新 名字修饰。...了解了函数调用约定和函数名修饰规则之后,再来看在C++程序中使用C语言编译库时经常出现LNK 2001错误就很简单了。...CB输出函数声明时使用4种修饰符号 : __cdecl cb 默认值,它会在输出函数名前加 "_",并保留此函数名不变,参数按照从右到左顺序依次传递给栈,也可以写成_cdeclcdecl形式...参数传递中,有两个很重要问题必须得到明确说明: 当参数个数多于一个时,按照什么顺序把参数压入堆栈 函数调用后,由谁来把堆栈恢复原状 高级语言中,通过函数调用约定来说明这两个问题。

2K31

5.5 汇编语言:函数调用约定

CDECL:C/C++默认调用约定调用方平栈,不定参数函数可以使用参数通过堆栈传递. STDCALL:被调方平栈,不定参数函数无法使用参数默认全部通过堆栈传递....CDECL是C/C++一种默认调用约定调用者平栈)。...CDECL调用约定特点是简单易用,但相比于其他调用约定,由于栈平衡操作需要在函数返回后再进行,因此一些情况下可能会带来一些性能上开销。...STDCALL是一种被调用者平栈约定,这意味着,函数调用过程中,被调用函数使用栈来存储传递参数,并在函数返回之前移除这些参数,这种方式可以使调用代码更短小简洁。...它通常采用被调用者平衡堆栈方式,类似于STDCALL调用约定。但是,FASTCALL约定规定函数前两个参数ECX和EDX寄存器中传递,节省了压入堆栈所需指令。

26620
  • 5.5 汇编语言:函数调用约定

    一般情况下在Win32环境默认遵循就是STDCALL,而在Win64环境下使用则是FastCALL,Linux系统上则遵循SystemV约定,这里我整理了他们之间异同点.CDECL:C/C++...默认调用约定调用方平栈,不定参数函数可以使用参数通过堆栈传递.STDCALL:被调方平栈,不定参数函数无法使用参数默认全部通过堆栈传递.FASTCALL32:被调方平栈,不定参数函数无法使用...CDECL调用约定特点是简单易用,但相比于其他调用约定,由于栈平衡操作需要在函数返回后再进行,因此一些情况下可能会带来一些性能上开销。...STDCALL是一种被调用者平栈约定,这意味着,函数调用过程中,被调用函数使用栈来存储传递参数,并在函数返回之前移除这些参数,这种方式可以使调用代码更短小简洁。...STDCALL与CDECL参数平衡上有所不同,其余部分都一样,但该约定不定参数函数无法使用

    32620

    2020-09-04:函数调用约定了解么?

    __thiscall thiscall是唯一一个不能明确指明函数修饰,因为thiscall不是关键字。它是C++类成员函数缺省调用约定。...由于成员函数调用还有一个this指针,因此必须特殊处理,thiscall意味着: 1) 参数从右向左入栈; 2) 如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,this指针在所有参数压栈后被压入堆栈...主要用于解决this指针问题,使用寄存器传递this指针。返回方式同__stdcall. 5.__nakedcall 这是一个很少见调用约定,一般程序设计者建议不要使用。...__pascal 基于Pascal语言调用约定参数从左至右入栈(与cdecl相反)。被调用者负责返回前清理堆栈。...函数返回值EAX或ST(0)中。保留寄存器有EBP, EBX, ESI和EDI。 optlinkIBM VisualAge编译器中被使用。 10.

    59910

    linux 编译 c或cpp 文件为动态库 so 文件(最简单直观模板)

    调用函数不会要求调用传递多少参数调用传递过多或者过少参数,甚至完全不同参数都不会产生编译阶段错误。...C中不加说明默认函数为_cdecl方式(C中也只能用这种方式),C++也一样,但是默认调用方式可以IDE环境中设置。...带有可变参数函数必须且只能使用_cdecl方式 __cdecl __fastcall与__stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数压栈顺序...1、__stdcall调用约定:函数参数自右向左通过栈传递,被调用函数返回前清理传送参数内存栈。 2、__cdecl是C和C++程序缺省调用方式。...5、nakedcall采用1-4调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器内容。

    5.7K40

    关于函数参数入栈思考(函数调用约定,入栈顺序)

    向被调函数传递参数,可以有不同方式实现。这些方式被称为“调用规范”或“调用约定”。C/C++中常见调用规范有__cdecl、__stdcall、__fastcall和__thiscall。...__cdecl调用约定 又称为C调用约定,是C/C++默认函数调用约定,它定义语法是: int function (int a ,int b) // 不加修饰就是C调用约定...使用__fastcall方式无法用作跨编译器接口。 __thiscall调用约定 是唯一一个不能明确指明函数修饰,因为thiscall不是关键字。它是C++类成员函数缺省调用约定。...由于成员函数调用还有一个this指针,因此必须特殊处理,thiscall意味着: (1) 参数从右向左入栈; (2) 如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,...---- 2.cout<<++i<<- -i<< i++;输出结果讨论 Visual C++函数调用规范中,如果函数任何一个参数表达式包含自增(自减)运算,所有这些运算会在第一个push操作之前全部完成

    2.6K31

    C语言 | C++ 堆栈工作机制

    我们知道,局部变量是存储堆栈中;debug 时,查看堆栈可以知道函数调用顺序;函数调用传递参数,事实上是把参数压入堆栈,听起来,堆栈象一个大杂烩。...有 2 个办法可以指定函数使用调用约定: 1)函数定义时加上修饰符来指定,如 void __thiscall mymethod();{ ...} 2) VS 工程设置中为工程中定义所有的函数指定默认调用约定...常用调用约定有以下3种: 1)__cdecl。这是 VC 编译器默认调用约定。其规则是:参数从右向左压入堆栈,函数退出时由 caller 清理堆栈中参数。...由于参数是由 callee 自己清理,所以 __stdcall 不支持可变数量参数。 3) __thiscall。类成员函数默认使用调用约定。...如果显式地把类成员函数声明为使用__cdecl或者__stdcall,那么,将采用__cdecl或者__stdcall规则来压栈和出栈,而this指针将作为函数第一个参数最后压入堆栈,而不是使用ECX

    7.8K88

    详解CC++堆栈工作机制

    我们知道,局部变量是存储堆栈中;debug时,查看堆栈可以知道函数调用顺序;函数调用传递参数,事实上是把参数压入堆栈,听起来,堆栈象一个大杂烩。那么,堆栈(Stack)到底是如何工作呢?...有2个办法可以指定函数使用调用约定: 1)函数定义时加上修饰符来指定,如: void __thiscall mymethod(); { ... } 2)VS工程设置中为工程中定义所有的函数指定默认调用约定...常用调用约定有以下3种: 1)__cdecl。这是VC编译器默认调用约定。其规则是:参数从右向左压入堆栈,函数退出时由caller清理堆栈中参数。...由于参数是由callee自己清理,所以__stdcall不支持可变数量参数。 3)__thiscall。类成员函数默认使用调用约定。...如果显式地把类成员函数声明为使用__cdecl或者__stdcall,那么,将采用__cdecl或者__stdcall规则来压栈和出栈,而this指针将作为函数第一个参数最后压入堆栈,而不是使用ECX

    48320

    大神洗礼第四讲——函数相关及编程技巧

    Author:bakari       Date:2012.11.2 1、参数传递问题: 、堆栈传参 、寄存器传参(利用通用寄存器进行函数参数传递方法) 、全局变量或静态变量传参...2、 Call Convention(函数调用约定) 、_cdecl a、 参数从右向左压入堆栈 b、 函数被调用者修改堆栈 c、 win32应用程序里,宏APIENTRY,WINAPI,...都表示_stdcall,非常常见. d、 C和C++程序缺省调用方式。...、_stdcall a、 压栈方式与_cdecl一样,与之不一样是堆栈平衡不是由函数调用者完成,而是自身完成,退出时自己清空堆栈。...3、 跟踪汇编代码看函数参数调用机制 我们看这样一个简单函数, 编译器翻译汇编指令如下: 、void Test1(){}  1 void Test1() 2 { 3 013516E0

    653100

    关于this指针

    this指针是类中非静态成员函数第一个默认隐含参数,编译器自动传递和维护,用户不可显示传递 函数调用约定 是指当一个函数被调用时,函数参数会被传递给被调用函数,返回值会被返回给调用函数,总之,就是函数调用者与被调函数之间关于参数传递...,返回值传递,堆栈清理,寄存器使用一种约定。...几种常用调用约定: 其中,_cdecl是C/C++默认调用约定,VC调用约定中并没有_thiscall这个关键字,它是类成员函数默认调用约定; C/C++main函数调用约定必须是_...对于_cdecl调用约定为什么调用者而不是函数体自己来平衡堆栈呢?...在这里我们应该要考虑类似于像scanf和printf这样函数,这里我们应该明白这两个函数参数都是可变如果参数不固定的话,在被调用函数内就无法知道参数究竟使用了多少个字节,所以为了实现可变参数,我们必须要在被调函数执行之后我们才知道参数究竟用了多少字节

    42910

    函数调用时堆栈变化情况

    环境下,以C/C++默认函数调用约定__cdecl来生成该程序调试版本(Debug)汇编代码。...Debug模式下,一个C/C++函数即使没有定义一个局部变量,仍然会分配192Bytes空间,供临时变量使用如果定义了局部变量,则会为每个局部变量分配12字节空间(大于任何基本数据类型)。...,结束函数 注意:以上汇编代码对mixAdd()函数调用采用函数调用约定是__cdecl,这是C/C++程序默认函数调用约定,其重要一点就是在被调用函数 (Callee) 返回后,由调用方 (Caller...return tmpi+tmpc; } 即将mixAdd()函数调用约定改为标准调用约定,那么mixAdd()函数结束时汇编代码会变成ret 8,main()函数调用mixAdd()地方会原本出现...有关函数调用约定介绍见我另一篇blog:关于函数参数入栈思考。

    76410

    调用约定

    使用IDAF5功能时经常能够看到函数签名中带有cdecl、fastcall等字样,这些就是调用约定调用约定是通常是特定于语言、编译器和CPU,这里只简单了解一下主流调用约定。...C调用约定cdecl)   x86体系结构许多C编译器使用默认调用约定叫做C调用约定cdecl)。...fastcall规定: 能够将最多两个参数存放在寄存器中 传递给函数前两个参数将分别位于ECX和EDX寄存器中 剩余参数以类似于stdcall约定方式从右往左放入栈上 C++调用约定(thiscall...)   C++类中非静态成员函数与标准函数不同,需要使用this指针,该指针指向用于调用函数对象。...用于调用函数对象地址必须由调用方提供,因此,他调用非静态成员函数时作为参数提供。C++语言标准未规定应如何向非静态成员函数传递this指针,因此,不同编译器使用不同技巧来传递this指针。

    86040

    CC++ 反汇编:关于函数调用约定

    一般编译器实现调用调用约定无外乎以下这几种: CDECL:C/C++默认调用约定调用方平栈,不定参数函数可以使用参数通过堆栈传递....而如果使用结束后没有恢复或过度恢复,则会造成栈上溢或下溢,给程序带来致命错误。...cdecl 调用者平栈: cdecl是C/C++默认调用约定,该调用方式函数内不进行任何平衡参数操作,而是退出函数后对esp执行加4操作,从而实现栈平衡。...stdcall 被调用者平栈: stdcall与cdecl参数平衡上有所不同,其余部分都一样,但该约定不定参数函数无法使用。...cdecl调用方式函数同一作用域内多次被调用,会在效率上比stdcall高一些,因为它可以使用复写传播优化,而stdcall函数内平衡栈,无法使用复写传播优化。

    62810

    请教关于C语言形参和实参存储单元问题?

    首先我们限定一下问题,只限于cdecl调用约定,函数没有被编译器做inline优化(C++才有inline,但是C编译器也可能自己把函数调用优化掉)。...除了cdecl以外,C中其他常用调用约定包括stdcall和fastcall,C++中还有一个thiscall(用于调用成员函数)。fastcall会使用寄存器来传递一部分参数。...stdcall除了返回时自动清理堆栈以外,与cdecl使用参数上区别不大。thiscall调用约定使用寄存器传递this指针参数。...pascal调用约定跟stdcall类似,但是参数入栈顺序是反cdecl调用约定下,所有参数从右往左入栈,都要占用存储空间。...是x86中调用约定,x64中已经不同了,查了一下相关资料,Windows上和非Windows上,使用调用约定是有差异

    1.2K30

    函数调用三种约定,你都清楚吗

    其中__cdecl是C/C++默认调用方式,__stdcall是windows API函数调用方式,只不过我们头文件里查看这些API声明时候是用了WINAPI宏进行代替了,而这个宏其实就是_...函数调用,涉及参数传递,返回值传递调用后返回,这都是通过栈变化来实现,对于三种调用约定而言: __cdecl: C/C++默认方式,参数从右向左入栈,主调函数负责栈平衡。...下面从实例来认识一下这三种调用约定。先来看一个简单不能再简单程序了: ? 三个函数内容都是一样,不同使用了三种调用方式。我们先来看看在main函数调用三个函数时候汇编代码: ?...说完了__cdecl和__stdcall,再来看看__fastcall,如前面图看到调用时并未使用push指令向栈里传参数,而是使用了 mov edx, 5 mov ecx, 2 两条指令...这样直接将参数传入寄存器,被调函数执行时候直接从寄存器取值即可,省去了从栈里取出来给寄存器,再从寄存器取出来放入内存。 不过,说个题外话,ecx寄存器经常作为计数和C++里this指针传递媒介。

    1.1K10

    C函数原理

    函数中参数传递 从上面的代码中可以看出,函数形参与实参并不是同一个变量,它们所在内存地址不同,这样就解释了为什么形参改变无法影响实参,只有通过传入地址才能改变实参。...另外从上面可以看出,当参数或者返回值大于4个字节时,都要经历内存拷贝,这样会大大降低效率,所以参数或者返回值大于4个字节时一般利用指针或者引用来传值,如果不想函数改变出入或者传出值,可以使用const...函数三种调用约定 我们知道函数中十分重要一个部分是对栈空间使用和最后栈空间回收,不同函数类型有不同参数压栈与栈空间还原方式,具体使用哪一种方式,需要事先与编译器约定好,以便生成对应机器码来处理...cdecl方式 这种方式是C/C++默认函数调用方式。...由于传递参数个数不确定,所以这个函数本身并不知道有多少个参数会传入,所以希望函数本身来平衡函数栈是不可能,只有调用之时才知道这个参数个数,所以平衡栈工作只能是由调用者来做,所以上述三种方式只有

    60630

    C++初阶】函数重载 && 引用

    注意 : 下面两个构造函数重载 调用存在歧义 1.2 C++支持函数重载原理--名字修饰(name Mangling) 为什么C++支持函数重载,而C语言不支持函数重载呢?...【扩展学习:C/C++函数调用约定和名字修饰规则--有兴趣好奇同学可以看看,里面 有对vs下函数名修饰规则讲解】 C/C++ 函数调用约定___declspec(dllexport) void...函数调用约定 常见函数调用约定[5]:cdecl,stdcall,fastcall,thiscall,naked call MFC调用约定(VS6:Project Settings->C/C++ Calling...convention:) 1, __cdecl(C调用约定.The C default calling convention)C/C++ 缺省调用方___declspec(dllexport) void...引用比指针使用起来相对更安全 10. 函数调用为了提高效率,常使用引用或指针作为函数参数传递变量或对象

    8010

    CC++ 反汇编:函数与结构体

    STDCALL调用约定,一般情况下在Win32环境默认遵循就是STDCALL,而在Win64环境下使用则是FastCALL,Linux系统上则遵循SystemV约定,这里我整理了他们之间异同点...这里我们来演示CDECL调用约定,其实我们使用Printf()函数就是遵循__cdecl()约定,由于Printf函数可以有多个参数传递,所以只能使用__cdecl()约定传递参数,该约定典型特点就是平栈不在被调用函数内部完成...与_stdcall两者只参数平衡上有所不同,其余部分都一样,但经过优化后_cdecl调用方式函数同一作用域内多次使用,会在效率上比_stdcall髙,这是因为_cdecl可以使用复写传播,而_stdcall...除了前面的两种调用约定以外_fastcall调用方式效率最髙,其他两种调用方式都是通过栈传递参数,唯独_fastcall可以利用寄存器传递参数,但由于寄存器数目很少,而参数相比可以很多,只能量力而行,...故Windows环境中_fastcall调用方式只使用了ECX和EDX寄存器,分别传递第1个参数和第2个参数,其余参数传递则依然使用堆栈传递.

    1.1K40

    你一定要搞明白C函数调用方式与栈原理

    另一方面,如果除了上面提到几个寄存器,被调用者还想使用别的寄存器,比如EBX,ESI和EDI,那么,被调用者就必须在栈中保存这些被额外使用寄存器,并在调用返回前回复他们。...也就是说,如果调用者只使用约定EAX,ECX和EDX寄存器,他们由调用者负责保存并回复,但如果调用这还额外使用了别的寄存器,则必须有他们自己保存并回复这些寄存器值。...如果返回值占用空间还要大,那么调用者会向被调用传递一个额外参数,这个额外参数指向将要保存返回值地址。...所以,C函数通常以这样指令结束: leave ret 调用返回后动作 程序控制权返回到调用者(也就是我们例子中main)后,栈如图5所示。这时,传递给foo参数通常已经不需要了。...(所谓__cdecl调用调用者负责恢复栈,调用者负责清理只是入栈参数,test函数自己堆栈空间自己返回时自己已经清除,靠!

    3.3K30

    python调用dll文件接口

    cdecl(这里强调调用约定是因为,stdcall调用约定cdecl调用约定声明导出函数,使用python加载时使用加载函数是不同,后面会有说明)调用约定导出函数Add。...cdecl中每个调用者都要嵌入处理代码,所以代码量会大一些。 但为什么不都用stdcall。...像printf这样函数,事先不知道需要栈大小,需要用cdecl来处理 所以需要使用cdecl调用   2、调用dll中方法 1中加载dll时候会返回一个DLL对象(假设名字叫Objdll...为什么把这个单独提出来说呢,因为这个是最麻烦也是最复杂python里面申明一个类似c结构体,要用到类,并且这个类必须继承自Structure。 ...,就是用C++调用win32 API来产生GUID,然后python通过调用C++dll来获得这个GUID。

    5.5K40
    领券