函数调用约定

  1. __stdcall
  2. __cdecl
  3. __fastcall

vc6.0:
int
__stdcall/__cdecl/__fastcall add(int x, int y)
{
 return x+y;
}

void main()
{
 add(2,3);
}

1.__stdcall:

1:    int __stdcall add(int x, int y)
2:    {
00401020   push       
ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
3:     return x+y;
00401038  
mov         eax,dword ptr [ebp+8]
0040103B   add        
eax,dword ptr [ebp+0Ch]
4:    }
0040103E   pop         edi
0040103F   pop         esi
00401040   pop         ebx
00401041   mov         esp,ebp
00401043   pop         ebp
00401044  
ret         8
5:
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3);
00401068   push       
3
0040106A   push        2
0040106C   call        @ILT+0(add) (00401005)
10:   }
00401071   pop        
edi
00401072   pop         esi
00401073   pop         ebx
00401074   add         esp,40h
00401077   cmp         ebp,esp
00401079   call        __chkesp (00401090)
0040107E   mov         esp,ebp
00401080   pop         ebp
00401081   ret

00401005  
jmp         add (00401020)

2.__cdecl:

1:    int __cdecl add(int x, int y)
2:    {
00401020   push       
ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
3:     return x+y;
00401038  
mov         eax,dword ptr [ebp+8]
0040103B   add        
eax,dword ptr [ebp+0Ch]
4:    }
0040103E   pop         edi
0040103F   pop         esi
00401040   pop         ebx
00401041   mov         esp,ebp
00401043   pop         ebp
00401044  
ret
5:
6:
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3);
00401068   push       
3
0040106A   push        2
0040106C   call        @ILT+10(add) (0040100f)
00401071   add        
esp,8
10:   }
00401074  
pop         edi
00401075   pop         esi
00401076   pop         ebx
00401077   add         esp,40h
0040107A   cmp         ebp,esp
0040107C   call        __chkesp (00401090)
00401081   mov         esp,ebp
00401083   pop         ebp
00401084   ret

0040100F   jmp         add (00401020)

3.__fastcall

1:    int __fastcall add(int x, int y)
2:    {
00401020   push       
ebp
00401021   mov         ebp,esp
00401023   sub         esp,48h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   push       
ecx
0040102A   lea         edi,[ebp-48h]
0040102D   mov         ecx,12h
00401032   mov         eax,0CCCCCCCCh
00401037   rep stos    dword ptr [edi]
0040103A   mov         dword ptr [ebp-8],edx
0040103D   mov         dword ptr [ebp-4],ecx
3:     return x+y;
00401040  
mov         eax,dword ptr [ebp-4]
00401043   add        
eax,dword ptr [ebp-8]
4:    }
00401046   pop         edi
00401047   pop         esi
00401048   pop         ebx
00401049   mov         esp,ebp
0040104B   pop         ebp
0040104C   ret
5:
6:
7:    void main()
8:    {
00401050   push       
ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3);
mov        
edx,3
0040106D   00401072   call        @ILT+15(add) (00401014)
10:   }
00401077   pop        
edi
00401078   pop         esi
00401079   pop         ebx
0040107A   add         esp,40h
0040107D   cmp         ebp,esp
0040107F   call        __chkesp (00401090)
00401084   mov         esp,ebp
00401086   pop         ebp
00401087   ret

00401014   jmp         add (00401020)
====================================================================================
1:    int __fastcall add(int x, int y, int z)
2:    {
0040D480   push       
ebp
0040D481   mov         ebp,esp
0040D483   sub         esp,48h
0040D486   push        ebx
0040D487   push        esi
0040D488   push        edi
0040D489   push        ecx
0040D48A   lea         edi,[ebp-48h]
0040D48D   mov         ecx,12h
0040D492   mov         eax,0CCCCCCCCh
0040D497   rep stos    dword ptr [edi]
0040D499   pop         ecx
0040D49A   mov         dword ptr [ebp-8],edx
0040D49D   mov         dword ptr [ebp-4],ecx
3:     return x+y+z;
0040D4A0  
mov         eax,dword ptr [ebp-4]
0040D4A3   add        
eax,dword ptr [ebp-8]
0040D4A6   add         eax,dword
ptr [ebp+8]
4:    }
0040D4A9  
pop         edi
0040D4AA   pop         esi
0040D4AB   pop         ebx
0040D4AC   mov         esp,ebp
0040D4AE   pop         ebp
0040D4AF   ret        
4
5:
6:
7:   
void main()
8:    {
00401050  
push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:     add(2,3,4);
push        4
0040106A   mov         edx,3
0040106F   mov         ecx,2
00401074   call        @ILT+20(add) (00401019)
10:   }
00401079   pop        
edi
0040107A   pop         esi
0040107B   pop         ebx
0040107C   add         esp,40h
0040107F   cmp         ebp,esp
00401081   call        __chkesp (00401090)
00401086   mov         esp,ebp
00401088   pop         ebp
00401089   ret

00401019   jmp         add (0040d480)

时间: 2024-10-05 17:07:18

函数调用约定的相关文章

汇编 ? cdecl 函数调用约定,stdcall 函数调用约定

知识点: ? cdecl 函数调用约定 ? stdcall 函数调用约定 ? CALL堆栈平衡 配置属性--> c/c++ -->高级-->调用约定 一.cdecl调用约定 VC++默认约定__cdecl 1.源代码 int __cdecl add1(int a,int b) { return a+b; } 2.生成汇编代码 00401000 /$ 55 PUSH EBP 00401001 |. 8BEC MOV EBP,ESP 00401003 |. 8B45 08 MOV EAX,D

C/C++函数调用约定

C/C++函数调用约定 函数声明部分的extern "C"表示连接规范(Linkage Specification)采用C,而不是C++.如果不写的 话.默认采用C++,当然也可以写成extern "C++". 1.__cdecl: C和C++默认的函数调用约定,参数从右到左顺序压入堆栈,由函数负责清理堆栈,把参数弹出. 也正是因为用来传送参数的堆栈是由调用函数维护的,所以实现可变参数的函数只能使用这种函数调用约定.因为每一个调用它的函数都要包含清理堆栈的代码,所以

C语言函数调用约定

在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就可以使用这个函数.但是,当高级语言被编译成计算机可以识别的机器码时,有一个问题就凸现出来:在CPU中,计算机没有办法知道一个函数调用需要多少个.什么样的参数,也没有硬件可以保存这些参数.也就是说,计算机不知道怎么给这个函数传递参数,传递参数的工作必须由函数调用者和函数本身来协调.为此,计算机提供了一种被称为栈的数据结构来支持参数传递. 栈

函数调用约定和堆栈

函数调用约定和堆栈 1 什么是堆栈 编译器一般使用堆栈实现函数调用.堆栈是存储器的一个区域,嵌入式环境有时需要程序员自己定义一个数组作为堆栈.Windows为每个线程自动维护一个堆栈,堆栈的大小可以设置.编译器使用堆栈来堆放每个函数的参数.局部变量等信息. 函数调用经常是嵌套的,在同一时刻,堆栈中会有多个函数的信息,每个函数占用一个连续的区域.一个函数占用的区域被称作帧(frame). 编译器从高地址开始使用堆栈. 假设我们定义一个数组a[1024]作为堆栈空间,一开始栈顶指针指向a[1023]

【系统篇】小议三种函数调用约定

小议三种函数调用约定 __cdecl.__stdcall.__fastcall是C/C++里中经常见到的三种函数调用方式.其中__cdecl是C/C++默认的调用方式,__stdcall是windows API函数的调用方式,只不过我们在头文件里查看这些API的声明的时候是用了WINAPI的宏进行代替了,而这个宏其实就是__stdcall了. 三种调用方式的区别相信大家应该有些了解,这篇文章主要从实例和汇编的角度阐述这些区别的表现形态,使其对它们的区别认识从理论向实际过渡. __cdecl: C

3 种关键函数调用约定

高级语言翻译成机器码后,计算机没有办法知道函数调用的参数个数.类型,也没有硬件可以保护这些参数. 另外,在C++中,因为重载的原因,所以对函数的命名方式和普通C语言并不一致,该方式称为名字改编. 函数调用者与函数之间,尤其是跨语言调用接口时,需要一个协议约定来传递参数——栈. 关键流程: 调用时,调用者依次把参数压栈,然后调用函数, 被调用函数,在堆栈中取得数据,并进行计算. 函数计算结束以后,或者调用者.或者函数本身修改堆栈,使堆栈恢复原装. 常见的函数调用约定: stdcall cdecl

c++函数调用约定学习(一)

函数调用约定 常见的函数调用约定[5]:cdecl,stdcall,fastcall,thiscall,naked call MFC调用约定(VS6:Project Settings->C/C++ <Category:Code Generation> Calling convention:) 1, __cdecl(C调用约定.The C default calling convention)C/C++ 缺省调用方式 1)压栈顺序:函数参数从右到左 2)参数栈维护:由调用函数把参数弹出栈,

__stdcall函数调用约定

__stdcall 被这个关键字修饰的函数,其参数都是从右向左通过堆栈传递的(__fastcall 的前面部分由ecx,edx传), 函数调用在返回前要由被调用者清理堆栈. 这个关键字主要见于Microsoft Visual C.C++.GNU的C.C++是另外一种修饰方式:__attribute__((stdcall)) 1函数调用约定 __stdcall是函数调用约定的一种,函数调用约定主要约束了两件事: 1.参数传递顺序 2.调用堆栈由谁(调用函数或被调用函数)清理 常见的函数调用约定:s

C++语言学习(十二)——C++语言常见函数调用约定

C++语言学习(十二)--C++语言常见函数调用约定 一.C++语言函数调用约定简介 C /C++开发中,程序编译没有问题,但链接的时候报告函数不存在,或程序编译和链接都没有错误,但只要调用库中的函数就会出现堆栈异常等现象.上述现象出现在C和C++的代码混合使用的情况下或在C++程序中使用第三方库(非C++语言开发)的情况下,原因是函数调用约定(Calling Convention)和函数名修饰(Decorated Name)规则导致的.函数调用约定决定函数参数入栈的顺序,以及由调用者函数还是被

x86函数调用约定

以下摘自<IDA Pro>,貌似有一些细节之处没有交代清楚呢,需要进一步思考.实践. 了解栈帧的基本概念后,接下来详细介绍它们的结构.下面的例子涉及x86体系结构和与常见的x86编译器(如Microsoft Visual C/C++或GNU的gcc/g++)有关的行为.创建栈帧的最重要的步骤是,通过调用函数将函数存入栈中.调用函数必须存储被调用函数所需要的参数,否则可能导致严重的问题.各个函数会选择并遵照某一特定的调用约定,以表明他们希望以何种方式接收参数. 调用约定指定调用方放置函数所需参数