<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    cdecl、pascal、stdcall、fastcall

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    Directive Parameter order   Clean-up Passes parameters in registers?
    register   Left-to-right         Routine        Yes
    pascal    Left-to-right           Routine     No
    cdecl    Right-to-left             Caller        No
    stdcall    Right-to-left           Routine     No
    safecall   Right-to-left          Routine     No

    調用約定           壓參數入棧順序     把參數彈出棧者         函數修飾名 
    (Calling convention) 
    --------------------------------------------------------------------------------------------------------
    __cdecl                 右->左             調用者                                 _function     
    __fastcall             右->左              被調用者                           @function@nnn      
    __stdcall             右->左               被調用者                           _function@nnn
    __pascal             左->右               被調用者                           _function@nnn
        
    -----------------------------------------------------------------------------------------------------------

    __cdecl是C/C++和MFC程序默認使用的調用約定,也可以在函數聲明時加上__cdecl關鍵字來手工指定。采用__cdecl約定時,函數參數按照從右到左的順序入棧,并且由調用函數者把參數彈出棧以清理堆棧。因此,實現可變參數的函數只能使用該調用約定。由于每一個使用__cdecl約定的函數都要包含清理堆棧的代碼,所以產生的可執行文件大小會比較大。__cdecl可以寫成_cdecl。
             __stdcall調用約定用于調用Win32 API函數。采用__stdcal約定時,函數參數按照從右到左的順序入棧,被調用的函數在返回前清理傳送參數的棧,函數參數個數固定。由于函數體本身知道傳進來的參數個數,因此被調用的函數可以在返回前用一條ret n指令直接清理傳遞參數的堆棧。__stdcall可以寫成_stdcall。
             __fastcall約定用于對性能要求非常高的場合。__fastcall約定將函數的從左邊開始的兩個大小不大于4個字節(DWORD)的參數分別放在ECX和EDX寄存器,其余的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的堆棧。__fastcall可以寫成_fastcall。 
    ·特別說明
    1. 在默認情況下,采用__cdecl方式,因此可以省略.
    2. WINAPI一般用于修飾動態鏈接庫中導出函數
    3. CALLBACK僅用于修飾回調函數

    便于更好理解, 看下面例子(函數調用的過程以匯編代碼表示):      
        
    void cdecl fun1(int x,int y); 
    void stdcall    fun2(int x,int y); 
    void pascal fun3(int x,int y);   
        

        
    **************************************** 

    void cdecl fun1(int x,int y); 

    fun1(x,y); 

    調用 fun1 的匯編代碼 

    push y 
    push x 
    call fun1 
    add sp,sizeof(x)+sizeof(y) ;跳過參數區(x,y) 

    fun1 的匯編代碼: 

    fun1 proc 
    push bp 
    mov bp,sp 
    …… 
     
    pop bp 
    ret ;返回,但不跳過參數區 
    fun1 endp 

    **************************************** 

    void stdcall fun2(int x,int y); 

    fun2(x,y); 

    調用 fun2 的匯編代碼 

    push y 
    push x 
    call fun2 

    fun2 的匯編代碼: 

    fun2 proc 
    push bp 
    mov bp,sp 
    …… 
     
    pop bp 
    ret sizeof(x)+sizeof(y) ;返回并跳過參數區(x,y) 
    fun2 endp 

    ***************************************** 

    void pascal fun3(int x,int y); 

    fun3(x,y); 

    調用 fun3 的匯編代碼 

    push x 
    push y 
    call fun3 

    fun3 的匯編代碼: 

    fun3 proc 
    push bp 
    mov bp,sp 
    …… 
     
    pop bp 
    ret sizeof(x)+sizeof(y) ;返回并跳過參數區(x,y) 
    fun3 endp  

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全