当前位置:编程学习 > 网站相关 >>

函数命名规则及调用约定(__cdecl,__stdcall,__fastcall)

函数命名规则及调用约定(__cdecl,__stdcall,__fastcall)
__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定。采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。
__stdcall调用约定用于调用Win32 API函数。采用__stdcall约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。
__fastcall约定用于对性能要求非常高的场合。__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的堆栈。__fastcall可以写成_fastcall
函数返回值传递方式
   其实,返回值的传递从处理上也可以想象为函数调用的一个out形参数; 函数返回值传递方式也是函数调用约定的一部分;
   有返回值的函数返回时:一般int、指针等32bit数据值(包括32bit结构)通过eax传递,(bool,char通过al传递,short通过ax传递),特别的__int64等64bit结构(struct) 通过edx,eax两个寄存器来传递(同理:32bit整形在16bit环境中通过dx,ax传递); 其他大小的结构(struct)返回时把其地址通过eax返回;(所以返回值类型不是1,2,4,8byte时,效率可能比较差)
   参数和返回值传递中,引用方式的类型可以看作与传递指针方式相同;
   float\double(包括Delphi中的extended)都是通过浮点寄存器st(0)返回;
下面是几个例子:
[cpp] view plaincopyprint?
global      _GetPowerAsm@8 
_GetPowerAsm@8: 
            PUSH    EBP             ; Save EBP 
            MOV     EBP, ESP        ; Move ESP into EBP so we can refer 
                                    ; to arguments on the stack 
            MOV     EAX, [EBP+4]    ; Get first argument 
            MOV     ECX, [EBP+6]    ; Get second argument 
            SHL     EAX, CL         ; EAX = EAX * (2 ^ CL) 
            POP     EBP             ; Restore EBP 
            RET 8            ;被调用者平衡堆栈    
             
global      _GetPowerAsm 
_GetPowerAsm: 
            PUSH    EBP             ; Save EBP 
            MOV     EBP, ESP        ; Move ESP into EBP so we can refer 
                                    ; to arguments on the stack 
            MOV     EAX, [EBP+4]    ; Get first argument 
            MOV     ECX, [EBP+6]    ; Get second argument 
            SHL     EAX, CL         ; EAX = EAX * (2 ^ CL) 
            POP     EBP             ; Restore EBP 
            RET                     ;调用者平衡堆栈 
   
   
global _sums@12  ;全局函数声明,表示这个函数要被外部文件调用 
 
_sums@12: 
 
 push ebp        ;保护ebp指针 
 
 mov ebp,esp 
 
 mov eax,[ebp+8] ;第一个入口参数int VAR1 
 
 add eax,[ebp+12];第二个入口参数相加int VAR2 
  
 add eax,[ebp+16];第三个入口参数相加int VAR3  
 
 pop ebp         ;恢复ebp指针 
 
 ret 12           ;被调用者平衡堆栈 
 
 
global _sums  ;全局函数声明,表示这个函数要被外部文件调用 
 
_sums: 
 
 push ebp        ;保护ebp指针 
 
 mov ebp,esp  www.zzzyk.com
 
 mov eax,[ebp+8] ;第一个入口参数int VAR1 
 
 add eax,[ebp+12];第二个入口参数相加int VAR2 
  
 add eax,[ebp+16];第三个入口参数相加int VAR3  
 
 pop ebp         ;恢复ebp指针 
 
 ret            ;调用者平衡堆栈         

补充:综合编程 , 其他综合 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,