青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

xiaoguozi's Blog
Pay it forword - 我并不覺的自豪,我所嘗試的事情都失敗了······習慣原本生活的人不容易改變,就算現狀很糟,他們也很難改變,在過程中,他們還是放棄了······他們一放棄,大家就都是輸家······讓愛傳出去,很困難,也無法預料,人們需要更細心的觀察別人,要隨時注意才能保護別人,因為他們未必知道自己要什么·····

 

左通過棧傳遞,被調用的函數在返回前清理傳送參數的內存棧,但不同的 是函數名的修飾部分(關于函數名的修飾部分在后面將詳細說明)。

_stdcall
Pascal程序的缺省調用方式,通常用于Win32 Api中,函數采用從右到左 的壓棧方式,自己在退出時清空堆棧。VC將函數編譯后會在函數名前面加上下劃線前綴,在函數名后加上"@"和參數的字節數。


2
C調 用約定(即用__cdecl關鍵字說明)按從右至左的順序壓參數入棧,由調用者把參數彈出棧。對于傳送參數的內存棧是由調用者來維護的(正因為如此,實現可變參數的函數只 能使用該調用約定)。另外,在函數名修飾約定方面也有所不同。


_cdecl
CC++程序的缺省調用方式。每一個調用它的函數都包含清空堆棧的代碼,所 以產生的可執行文件大小會比調用_stdcall函數的大。函數采用從右到左的壓棧方式。VC將函數編譯后會在函數名前面加上下劃線前綴。是MFC缺省調用約定。


3
__fastcall調用約定是“人”如其名,它的主要特點就是快,因為它是通過寄存器來傳送參數的(實際上,它用ECXEDX傳送前兩個雙字(DWORD)或更小的參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返 回前清理傳送參數的內存棧),在函數名修飾約定方面,它和前兩者均不同。


_fastcall
方式的函數采用寄存器傳遞參數,VC將函數編譯后會在函數名前面加上"@"前綴,在函數名后加上"@"和參數的字節數。


4
thiscall僅僅應用于“C++”成員函數。this指針存放于CX寄存器,參數從右到左壓。thiscall不是關鍵詞,因此不能被程序員指定。


5
naked call采用1-4的調用約定時,如果必要的話,進入函數時編譯器會產生代碼來保存ESIEDIEBXEBP寄存器,退出函數時則產生代碼恢復這些寄存器的內容。naked call不產生這樣的代碼。naked call不是類型修飾符,故 必須和_declspec共同使用。


關鍵字 __stdcall__cdecl__fastcall可以直接加在要輸出的函數前,也可以在編譯環境的Setting...\C/C++ \Code Generation項選擇。當加在輸出函數前的關鍵字與編譯環境中的選擇不同時,直接加在輸出函數前的關鍵字有效。它們對應的命令行參數分別為/Gz/Gd/Gr。缺省狀態為/Gd,即__cdecl


要完全模仿PASCAL調用約定首先必須使用__stdcall調用約定,至于函數名修飾約定,可以通過其它方法模仿。還有一個值得 一提的是WINAPI宏,Windows.h支持該宏,它可以將出函數翻譯成適當的調用約定,在WIN32中,它被定義為__stdcall。使用WINAPI宏可以創建自己的APIs


2)
名字修飾約定


1
、修飾名
(Decoration name)

C”或者“C++”函數在內部(編譯和鏈接)通過修飾名識別。修飾名是編譯器在編譯函 數定義或者原型時生成的字符串。有些情況下使用函數的修飾名是必要的,如在模塊定義文件里頭指定輸出“C++”重載函數、構造函數、析構函數,又如在匯編代碼里調用“C””或“C++”函數等。


修飾名由函數名、類名、調用約定、返回類型、參數等共同決定。


2
、名字修飾約定隨調用約定和編譯種類(CC++)的不同而變化。函數名修飾約定隨編譯種類和調用約定的不同而不同,下 面分別說明。


a
C編譯時函數名修飾約定規則:


__stdcall
調用約定在輸出函數名前加上一個下劃線前綴,后面加上一個“@”符號和其參數的字節數,格式為_functionname@number


__cdecl
調用約定僅在輸出函數名前加上一個下劃線前綴,格式為_functionname


__fastcall
調用約定在輸出函數名前加上一個“@”符號,后面也是一個“@”符號和其參數的字節數,格式為@functionname@number


它們均不改變輸出函數名中的字符大小寫,這和PASCAL調用約定不同,PASCAL約定輸出的函數名無任何修飾且全部大寫。


b
C++編 譯時函數名修飾約定規則:


__stdcall
調用約定:

1
、 以“?”標識函數 名的開始,后跟函數名;

2
、函數名后面以“@@YG”標識參數表的開始,后跟參數表;

3
、 參數表以代號表示:

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--
表示指 針,后面的代號表明指針類型,如果相同類型的指針連續出現,以“0”代替,一個“0”代表一次重復;

4
、 參數表的第一項為該函數的返回值類型,其后依次為參數的數據類型,指針標識在其所指數據類型前;

5
、 參數表后以“@Z” 標識整個名字的結束,如果該函數無參數,則以“Z”標識結束。


其格式為“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,例如

int Test1
char *var1,unsigned long-----?Test1@@YGHPADK@Z

void Test2
() -----?Test2@@YGXXZ


__cdecl
調用約定:

規 則同上面的_stdcall調用約定,只是參數表的開始標識由上面的“@@YG”變為“@@YA”。


__fastcall
調用約定:

規 則同上面的_stdcall調用約定,只是參數表的開始標識由上面的“@@YG”變為“@@YI”。


VC++
對函數的省缺聲明是"__cedcl",將只能被C/C++調用
.

CB
在輸出函數聲明時使用4種修飾符號

//__cdecl
cb
的默認值,它會在輸出函數名前加_,并保留此函數名不變,參數按照從右到左的順序依次傳遞給棧,也可以寫 成_cdeclcdecl形式。

//__fastcall
她修飾的函數的參 數將盡肯呢感地使用寄存器來處理,其函數名前加@,參數按照從左到右的順序壓棧;

//__pascal
它說明的函數名使 用Pascal格 式的命名約定。這時函數名全部大寫。參數按照從左到右的順序壓棧;

//__stdcall
使用標準約定的函 數名。函數名不會改變。使用__stdcall修飾時。參數按照由右到左的順序壓棧,也可以是_stdcall


TITLE  : __stdcall與__cdecl的區別
AUTHOR : lionel@nkbbs.org
DATE   : 
01/10/2005

CONTENT:

    Visual C
++ Compiler Options可以指定的Calling Convention有 3種:
   
    
/Gd /Gr /Gz
   
    這三個參數決定了:
   
    
1.函數參數以何種順序入棧,右到左還是左到右。
    
2.在函數運行完后,是調用函數還是被調用函數清理入棧的參數。
    
3.在編譯時函數名字是如何轉換的。
   
    下面我們分別詳細介紹:
   
    
1./Gd
        這是編譯器默認的轉換模式,對一般函數使用 C的函數調用轉換方式__cdecl,
        但是對于C
++ 成員函數和前面修飾了__stdcall __fastcall的函數除外。
       
    
2./Gr
        對于一般函數使用__fastcall函數調用轉換方式,所有使用__fastcall的函數
        必須要有函數原形。但對于C
++ 成員函數和前面修飾了__cdecl __stdcall 的
        函數除外。
       
    
3./Gz
        對于所有 C函數使用__stdcall函數調用轉換方式,但對于可變參數的 C函數以
        及用__cdecl __fastcall修飾過的函數和C
++ 成員函數除外。所有用__stdcall
        修飾的函數必須有函數原形。
       
        事實上,對于x86系統,C
++ 成員函數的調用方式有點特別,將成員函數的this
        指針放入ECX,所有函數參數從右向左入棧,被調用的成員函數負責清理入棧的
        參數。對于可變參數的成員函數,始終使用__cdecl的轉換方式。
       
    下面該進入主題,分別講一下這三種函數調用轉換方式有什么區別:
   
    
1.__cdecl
        這是編譯器默認的函數調用轉換方式,它可以處理可變參數的函數調用。參數
        的入棧順序是從右向左。在函數運行結束后,由調用函數負責清理入棧的參數。
        在編譯時,在每個函數前面加上下劃線(_),沒有函數名大小寫的轉換。即
       
          _functionname
       
    
2.__fastcall
        有一些函數調用的參數被放入ECX,EDX中,而其它參數從右向左入棧。被調用
        函數在它將要返回時負責清理入棧的參數。在內嵌匯編語言的時候,需要注意
        寄存器的使用,以免與編譯器使用的產生沖突。函數名字的轉換是:
       
          @functionname@number
       
        沒有函數名大小寫的轉換,number表示函數參數的字節數。由于有一些參數不
        需要入棧,所以這種轉換方式會在一定程度上提高函數調用的速度。
       
    
3.__stdcall
      函數參數從右向左入棧,被調用函數負責入棧參數的清理工作。函數名轉換格
      式如下:
   
        _functionname@number
   
    下面我們親自寫一個程序,看看各種不同的調用在編譯后有什么區別,我們的被調
    用函數如下:
   
    
int function(int a, int b)
    {
        
return a + b;
    }
   
    
void main()
    {
        function(
1020);
    }
   
    
1.__cdecl
       
        _function

                 push    ebp
                 mov     ebp, esp
                 mov     eax, [ebp
+8]       ;參數1
                 add     eax, [ebp
+C]       ;加上參數2
                 pop     ebp
                 retn

        _main
                 push    ebp
                 mov     ebp, esp
                 push    14h                ;參數 2入棧
                 push    0Ah                ;參數 1入棧
                 call    _function          ;調用函數
                 add     esp, 
8             ;修正棧
                 xor     eax, eax
                 pop     ebp
                 retn
                
    
2.__fastcall
   
        @function@
8
                 push    ebp
                 mov     ebp, esp           ;保存棧指針
                 sub     esp, 
8             ;多了兩個局部變量
                 mov     [ebp
-8], edx       ;保存參數 2
                 mov     [ebp
-4], ecx       ;保存參數 1
                 mov     eax, [ebp
-4]       ;參數 1
                 add     eax, [ebp
-8]       ;加上參數 2
                 mov     esp, ebp           ;修正棧
                 pop     ebp
                 retn

        _main
                 push    ebp
                 mov     ebp, esp
                 mov     edx, 14h           ;參數 2給EDX
                 mov     ecx, 0Ah           ;參數 1給ECX
                 call    @function@
8        ;調用函數
                 xor     eax, eax
                 pop     ebp
                 retn
 
    
3.__stdcall
   
        _function@
8

                 push    ebp
                 mov     ebp, esp
                 mov     eax, [ebp]         ;參數 
1
                 add     eax, [ebp
+C]       ;加上參數 2
                 pop     ebp
                 retn    
8                  ;修復棧

        _main
                 push    ebp
                 mov     ebp, esp
                 push    14h                ;參數 2入棧
                 push    0Ah                ;參數 1入棧 
                 call    _function@
8    ;函數調用
                 xor     eax, eax
                 pop     ebp
                 retn

    可見上述三種方法各有各的特點,而且_main必須是__cdecl,一般WIN32的函數都是
    __stdcall。而且在Windef.h中有如下的定義:
   
    
#define CALLBACK __stdcall
    
#define WINAPI  __stdcall

posted on 2010-07-01 09:27 小果子 閱讀(281) 評論(0)  編輯 收藏 引用 所屬分類: 學習筆記
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            一区二区免费在线播放| 欧美激情小视频| 日韩视频免费大全中文字幕| 欧美日韩一区国产| 欧美国产日韩免费| 久久夜色精品国产| 午夜精品久久久99热福利| 一区二区三区四区五区精品视频| 欧美成人综合| 亚洲激情一区| 亚洲电影成人| 99精品视频免费| 亚洲伊人观看| 久久精品官网| 欧美国产高清| 国产精品麻豆va在线播放| 欧美日韩在线精品一区二区三区| 欧美日韩精品一区| 很黄很黄激情成人| 一本到12不卡视频在线dvd| 欧美成人精品三级在线观看| 亚洲国产精品一区在线观看不卡 | 奶水喷射视频一区| 亚洲激情在线观看| 欧美一区亚洲| 欧美日韩国产不卡在线看| 国产一区二区三区高清播放| 亚洲国产美国国产综合一区二区| 亚洲另类在线一区| 久久精品国产99精品国产亚洲性色| 久久三级视频| 亚洲视频在线一区| 欧美一区二区成人| 欧美国产日韩免费| 亚洲欧美日韩直播| 欧美午夜一区二区福利视频| 狠狠久久婷婷| 狼人社综合社区| 亚洲天堂激情| 国产精品久久久久久久久久三级| 亚洲二区视频| 亚洲人成在线播放网站岛国| 老色鬼精品视频在线观看播放| 国产日本精品| 久久婷婷亚洲| 欧美成年网站| 亚洲午夜一区二区三区| 日韩视频免费观看高清完整版| 欧美国产精品v| 亚洲在线播放电影| 久久精品一区中文字幕| 韩国精品久久久999| 免费在线亚洲| 国产精品久久久久三级| 久久久久久亚洲精品不卡4k岛国| 欧美中文字幕第一页| 在线不卡免费欧美| 亚洲精品久久久久中文字幕欢迎你| 欧美韩国日本一区| 性做久久久久久| 免费一级欧美片在线播放| 亚洲小说欧美另类社区| 久久久久国产免费免费| 在线亚洲免费视频| 欧美国产欧美亚洲国产日韩mv天天看完整 | 国产一区二区三区免费观看| 美国十次成人| 国产精品盗摄一区二区三区| 裸体一区二区三区| 国产精品一级| 一区二区三区久久| 亚洲理论在线观看| 欧美国产国产综合| 亚洲黑丝在线| 亚洲美女尤物影院| 欧美精品在线观看一区二区| 麻豆精品在线观看| 黄色免费成人| 久久精品在线播放| 久热精品在线视频| 曰韩精品一区二区| 久久久人人人| 亚洲成在人线av| 亚洲美女在线国产| 欧美色道久久88综合亚洲精品| 亚洲国产精品一区二区第四页av | 国产视频精品网| 亚洲欧美影音先锋| 久久久国产精品一区二区中文 | 国产精品免费久久久久久| 一区二区三区日韩精品视频| 亚洲一区二区影院| 国产欧美日韩一级| 久久久www成人免费无遮挡大片| 开心色5月久久精品| 亚洲精品日产精品乱码不卡| 欧美国产一区二区在线观看| 亚洲午夜国产一区99re久久| 欧美日韩福利在线观看| 亚洲欧美在线一区二区| 欧美成人伊人久久综合网| 日韩亚洲视频| 久久久中精品2020中文| 亚洲国产精品精华液2区45| 亚洲免费在线视频一区 二区| 国产视频自拍一区| 亚洲黄色av一区| 精品51国产黑色丝袜高跟鞋| 麻豆亚洲精品| 久久国产精品亚洲va麻豆| 亚洲激情视频网站| 另类欧美日韩国产在线| 亚洲一区免费视频| 一区二区久久久久| 亚洲人线精品午夜| 国产午夜亚洲精品不卡| 欧美日韩国产片| 欧美精品在线一区二区| 蜜月aⅴ免费一区二区三区| 午夜一区在线| 久久成人亚洲| 香港久久久电影| 性欧美18~19sex高清播放| 中文av一区二区| 亚洲免费中文字幕| 欧美一区中文字幕| 久久综合给合久久狠狠色 | 性一交一乱一区二区洋洋av| 亚洲特级片在线| 久久精品系列| 亚洲啪啪91| 亚洲欧美日本国产有色| 久久久精品久久久久| 欧美激情第9页| 黑人一区二区三区四区五区| 亚洲精品美女91| 久久婷婷国产麻豆91天堂| 欧美福利在线观看| 国产精品日韩欧美综合 | 国产精品美女主播| 亚洲国产成人久久综合一区| 99精品视频免费全部在线| 亚洲欧美日韩精品久久久久| 免费成人在线观看视频| 日韩一级免费| 欧美精品激情在线观看| 红杏aⅴ成人免费视频| 亚洲综合电影| 夜夜嗨av一区二区三区四区| 久久久久久亚洲综合影院红桃| 欧美视频中文在线看 | 欧美亚洲日本一区| 国产精品美女久久| 一区二区av在线| 亚洲日本精品国产第一区| 宅男噜噜噜66国产日韩在线观看| 一本久道综合久久精品| 久久成人av少妇免费| 亚洲欧美一区二区激情| 国产精品久久激情| 亚洲视频图片小说| 一区二区av| 国产日韩欧美精品| 欧美在线999| 久久国产日本精品| 亚洲第一网站| 一区二区欧美国产| 国产精品一区视频| 久久综合色婷婷| 欧美成人午夜免费视在线看片 | 免费一区二区三区| 一区二区高清在线观看| 99精品视频免费全部在线| 亚洲日本成人| 国产精品一区视频网站| 久久精品国产亚洲aⅴ| 欧美 日韩 国产精品免费观看| 亚洲片在线资源| 亚久久调教视频| 一区二区三区视频在线播放| 亚洲一区视频在线观看视频| 亚洲激情啪啪| 久久视频精品在线| 狠狠色伊人亚洲综合成人| 亚洲成人资源网| 国产一区二区三区黄视频| 亚洲高清在线观看一区| 国产精品日本一区二区| 91久久精品一区二区别| 在线成人欧美| 久久国产66| 麻豆精品精品国产自在97香蕉| 欧美日韩一区国产| 日韩网站在线观看| 亚洲一二区在线| 国产精品乱人伦中文| 亚洲一区二区免费在线| 亚洲深夜av| 国产欧美日韩专区发布| 午夜精品成人在线视频|