• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            匯編說明__cdecl,__stdcall,__fastcall的差異

            1.如果函數(shù)func__cdecl(C/C++默認調(diào)用方式,實現(xiàn)可變參數(shù)函數(shù)),調(diào)用時情況如下  
             

            clip_image001int   main() 
            clip_image002clip_image003 
            ...
            clip_image004 
            //
            參數(shù)從右到左壓棧 
            clip_image004
              push   4 
            clip_image004  push   3 
            clip_image004  push   2 
            clip_image004  push   1 
            clip_image004  call   func 
            clip_image004  add   esp   0x10  
            //調(diào)用者恢復(fù)堆棧指針esp4個參數(shù)的大小是0x10(4x4) 
            clip_image005
              }  


               
              2.
            如果函數(shù)func__stdcall(最多語言支持的方式,COM規(guī)范標準),調(diào)用時情況如下  
             

            clip_image001int   main() 
            clip_image002clip_image003 
            ...
            clip_image004 
            //
            參數(shù)從右到左壓棧 
            clip_image004
              push   4 
            clip_image004  push   3 
            clip_image004  push   2 
            clip_image004  push   1 
            clip_image004  call   func 
            clip_image004               
            //恢復(fù)堆棧指針由被調(diào)用者func負責,方法是"ret   0x10" 
            clip_image005
              }  


               
              3.
            如果函數(shù)func__pascal,調(diào)用情況如下  
             

            clip_image001int   main() 
            clip_image002clip_image003 
            ...
            clip_image004 
            //
            參數(shù)從左到右壓棧 
            clip_image004
              push   1 
            clip_image004  push   2 
            clip_image004  push   3 
            clip_image004  push   4 
            clip_image004  call   func 
            clip_image004 
            //恢復(fù)堆棧指針由被調(diào)用者func負責,方法是"ret   0x10" 
            clip_image005
              }  


               
              3.
            如果函數(shù)func__fastcall(寄存器傳參),調(diào)用情況如下  
             

            clip_image001int   main() 
            clip_image002clip_image003 
            ...
            clip_image004 
            //
            參數(shù)先用ecx,   edx,   eax傳遞,然后再壓棧 
            clip_image004  //
            不進棧 
            clip_image004  //(
            不知為什么,幫助中寫的是從左到右傳遞的, 
            clip_image004  //
            是不是錯了,還是bcb6bcb5的不一樣
            clip_image004
              push   4 
            clip_image004  mov   ecx 3 
            clip_image004  mov   edx 2 
            clip_image004  mov   eax 1 
            clip_image004  call   func 
            clip_image004 
            //恢復(fù)堆棧指針由被調(diào)用者func負責,方法是"ret   0x04", 
            clip_image004  //
            因為只進棧一個參數(shù),其余用寄存器傳遞,所以用ret   0x04恢復(fù) 
            clip_image005
              }  


             

            發(fā)表者:huang_jh

             
              #define   callback         __stdcall  
               
              #define   winapi             __stdcall  
               
             
            定義成不同的名字只是為了"望文知意"就像hwndhcursor是一樣的類型.  
             
            他們都是窗口函數(shù)(過程)......  
             

            發(fā)表者:sinman

            我收集的,全仍上來了  
               
             
            左通過棧傳遞,被調(diào)用的函數(shù)在返回前清理傳送參數(shù)的內(nèi)存棧,但不同的是函數(shù)名的修飾部分。  
               
                     _stdcall
            pascal程序的缺省調(diào)用方式,通常用于win32   api,函數(shù)采用從右到左的壓棧方式,自己在退出時清空堆棧。vc將函數(shù)編譯后會在函數(shù)名前面加上下劃線前綴,在函數(shù)名后加上"@"和參數(shù)的字節(jié)數(shù)。  
               
            2
            c調(diào)用約定按從右至左的順序壓參數(shù)入棧,由調(diào)用者把參數(shù)彈出棧。對于傳送參數(shù)的內(nèi)存棧是由調(diào)用者來維護的。另外,在函數(shù)名修飾約定方面也有所不同。  
               
                      _cdecl
            cc++程序的缺省調(diào)用方式。每一個調(diào)用它的函數(shù)都包含清空堆棧的代碼,所以產(chǎn)生的可執(zhí)行文件大小會比調(diào)用_stdcall函數(shù)的大。函 數(shù)采用從右到左的壓棧方式。vc將函數(shù)編譯后會在函數(shù)名前面加上下劃線前綴。是mfc缺省調(diào)用約定。  
               
                      3
            __fastcall調(diào)用約定是如其名,它的主要特點就是快,因為它是通過寄存器來傳送參數(shù)的或更小的參數(shù),剩下的參數(shù)仍舊自右向左壓棧傳送,被調(diào)用的函數(shù)在返回前清理傳送參數(shù)的內(nèi)存棧),在函數(shù)名修飾約定方面,它和前兩者均不同。  
               
                      _fastcall
            方式的函數(shù)采用寄存器傳遞參數(shù),vc將函數(shù)編譯后會在函數(shù)名前面加上"@"前綴,在函數(shù)名后加上"@"和參數(shù)的字節(jié)數(shù)。          
               
                      4
            thiscall僅僅應(yīng)用于“c++”成員函數(shù)。this指針存放于cx寄存器,參數(shù)從右到左壓。thiscall不是關(guān)鍵詞,因此不能被程序員指定。  
               
                      5
            naked   call采用1-4的調(diào)用約定時,如果必要的話,進入函數(shù)時編譯器會產(chǎn)生代碼來保存esiediebxebp寄存器,退出函數(shù)時則產(chǎn)生代碼恢復(fù)這些寄存器的內(nèi)容。naked   call不產(chǎn)生這樣的代碼。naked   call不是類型修飾符,故必須和_declspec共同使用。  
               
                     
            關(guān)鍵字   __stdcall__cdecl__fastcall可以直接加在要輸出的函數(shù)前,也可以在編譯環(huán)境的setting...\c/c++   \code   generation項選擇。當加在輸出函數(shù)前的關(guān)鍵字與編譯環(huán)境中的選擇不同時,直接加在輸出函數(shù)前的關(guān)鍵字有效。它們對應(yīng)的命令行參數(shù)分別為/gz /gd/gr。缺省狀態(tài)為/gd,即__cdecl  
               
                     
            要完全模仿pascal調(diào)用約定首先必須使用__stdcall調(diào)用約定,至于函數(shù)名修飾約定,可以通過其它方法模仿。還有一個值得一提的是winapi 宏,windows.h支持該宏,它可以將出函數(shù)翻譯成適當?shù)恼{(diào)用約定,在win32中,它被定義為__stdcall。使用winapi宏可以創(chuàng)建自己 的apis  
               
              2)
            名字修飾約定  
               
              1
            、修飾名(decoration   name)  
               
              “c”
            或者“c++”函數(shù)在內(nèi)部通過修飾名識別。修飾名是編譯器在編譯函數(shù)定義或者原型時生成的字符串。有些情況下使用函數(shù)的修飾名是必要的,如在模塊定義文件里頭指定輸出“c++”重載函數(shù)、構(gòu)造函數(shù)、析構(gòu)函數(shù),又如在匯編代碼里調(diào)用“c””“c++”函數(shù)等。  
               
             
            修飾名由函數(shù)名、類名、調(diào)用約定、返回類型、參數(shù)等共同決定。  
               
              2
            、名字修飾約定隨調(diào)用約定和編譯種類(cc++)的不同而變化。函數(shù)名修飾約定隨編譯種類和調(diào)用約定的不同而不同,下面分別說明。  
               
                      a
            c編譯時函數(shù)名修飾約定規(guī)則:  
               
                __stdcall
            調(diào)用約定在輸出函數(shù)名前加上一個下劃線前綴,后面加上一個“@”符號和其參數(shù)的字節(jié)數(shù),格式為_functionname@number  
               
                __cdecl
            調(diào)用約定僅在輸出函數(shù)名前加上一個下劃線前綴,格式為_functionname  
                     
                __fastcall
            調(diào)用約定在輸出函數(shù)名前加上一個“@”符號,后面也是一個“@”符號和其參數(shù)的字節(jié)數(shù),格式為@functionname@number  
               
                     
            它們均不改變輸出函數(shù)名中的字符大小寫,這和pascal調(diào)用約定不同,pascal約定輸出的函數(shù)名無任何修飾且全部大寫。  
               
                      b
            c++編譯時函數(shù)名修飾約定規(guī)則:  
               
              __stdcall
            調(diào)用約定:  
                                  1
            、以“?”標識函數(shù)名的開始,后跟函數(shù)名;  
                                  2
            、函數(shù)名后面以“@@yg”標識參數(shù)表的開始,后跟參數(shù)表;  
                                  3
            、參數(shù)表以代號表示:  
                                        x--void  
              
                                        d--char
             
                                        e--unsigned   char
              
                                        f--short
              
                                        h--int
              
                                        i--unsigned   int
              
                                        j--long
              
                                        k--unsigned   long
              
                                        m--float
              
                                        n--double
              
                                        _n--bool
              
                                        ....  
                                        pa--
            表示指針,后面的代號表明指針類型,如果相同類型的指針連續(xù)出現(xiàn),以“0”代替,一個“0”代表一次重復(fù);  
                                  4
            、參數(shù)表的第一項為該函數(shù)的返回值類型,其后依次為參數(shù)的數(shù)據(jù)類型,指針標識在其所指數(shù)據(jù)類型前;    
                                  5
            、參數(shù)表后以“@z”標識整個名字的結(jié)束,如果該函數(shù)無參數(shù),則以“z”標識結(jié)束。  
               
                     
            其格式為“?functionname@@yg*****@z”“?functionname@@yg*xz”,例如  
                                  int   test1-----“?test1@@yghpadk@z”  
                                  void   test2                                               -----“?test2@@ygxxz”  
               
              __cdecl
            調(diào)用約定:  
             
            規(guī)則同上面的_stdcall調(diào)用約定,只是參數(shù)表的開始標識由上面的“@@yg”變?yōu)?span lang="EN-US">“@@ya”
              
               
              __fastcall
            調(diào)用約定:  
             
            規(guī)則同上面的_stdcall調(diào)用約定,只是參數(shù)表的開始標識由上面的“@@yg”變?yōu)?span lang="EN-US">“@@yi”。  
               
                      vc++
            對函數(shù)的省缺聲明是"__cedcl",將只能被c/c++調(diào)用.  
               
              cb
            在輸出函數(shù)聲明時使用4種修飾符號  
              //__cdecl  
              cb
            的默認值,它會在輸出函數(shù)名前加_,并保留此函數(shù)名不變,參數(shù)按照從右到左的順序依次傳遞給棧,也可以寫成_cdeclcdecl形式。  
              //__fastcall  
             
            她修飾的函數(shù)的參數(shù)將盡肯呢感地使用寄存器來處理,其函數(shù)名前加@,參數(shù)按照從左到右的順序壓棧;  
              //__pascal  
             
            它說明的函數(shù)名使用pascal格式的命名約定。這時函數(shù)名全部大寫。參數(shù)按照從左到右的順序壓棧;  
              //__stdcall  
             
            使用標準約定的函數(shù)名。函數(shù)名不會改變。使用__stdcall修飾時。參數(shù)按照由右到左的順序壓棧,也可以是_stdcall

            發(fā)表者:echoher

            far是古代的東西  
               
             
            16位模式下,指針是16位的  
             
            指針的尋址空間只有64k  
             
            如果指定far,說明這個指針指向的地址要加上基地址  
             
            就是說用far可以指定64k以外的區(qū)域  
               
             
            現(xiàn)在已經(jīng)沒用了  
             
            一點用也沒有了

             

            posted on 2011-01-10 13:38 肥仔 閱讀(1525) 評論(1)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

            評論

            # re: 匯編說明__cdecl,__stdcall,__fastcall的差異[未登錄]  回復(fù)  更多評論   

            太深奧,有點看不懂啊
            2012-11-08 17:12 | 歲月漫步
            国产99久久九九精品无码| 一本久久知道综合久久| 久久免费视频观看| 久久亚洲精品无码播放| 欧美亚洲国产精品久久久久| 久久精品a亚洲国产v高清不卡| 国产精品久久99| 久久人人爽人人爽人人片AV东京热 | 久久久久亚洲精品中文字幕| 久久久久久久综合狠狠综合| 精品久久久久久| 欧美亚洲国产精品久久| 国产精品免费久久久久久久久| 免费精品久久天干天干| 国产精品免费久久久久久久久| 无码人妻久久一区二区三区免费丨 | 66精品综合久久久久久久| 亚洲日本va午夜中文字幕久久| 99久久中文字幕| 亚洲精品乱码久久久久久蜜桃图片| 很黄很污的网站久久mimi色| 久久不见久久见免费视频7| 亚洲va久久久久| 伊人久久无码精品中文字幕| 日韩亚洲欧美久久久www综合网| 伊人色综合久久天天人手人婷 | 久久久无码精品亚洲日韩京东传媒 | 久久九九久精品国产免费直播| Xx性欧美肥妇精品久久久久久| 91精品国产91久久综合| 久久久婷婷五月亚洲97号色| 久久国语露脸国产精品电影| 久久亚洲精品国产亚洲老地址| 亚洲国产天堂久久综合| 久久精品综合一区二区三区| 亚洲午夜精品久久久久久人妖| 久久久久久狠狠丁香| 国产精品日韩深夜福利久久 | 久久综合久久伊人| 久久精品国产99久久丝袜| 久久精品国产亚洲综合色|