• <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>

              C++博客 :: 首頁 :: 聯系 ::  :: 管理
              163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(48)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 400068
            • 排名 - 59

            最新評論

            閱讀排行榜

            評論排行榜

            stdcall很多時候被稱為pascal調用約定,因為pascal是早期很常見的一種教學用計算機程序設計語言,其語法嚴謹,使用的函數調用約定就是 stdcall。在Microsoft C++系列的C/C++編譯器中,常常用PASCAL宏來聲明這個調用約定,類似的宏還有WINAPI和 CALLBACK。
            stdcall調用約定聲明的語法為(以前文的那個函數為例):
            int __stdcall function(int a,int b)
            stdcall的調用約定意味著:1)參數從右向左壓入堆棧,2)函數自身修改堆棧 3)函數名自動加前導的下劃線,后面緊跟一個@符號,其后緊跟著參數的尺寸
            以上述這個函數為例,參數b首先被壓棧,然后是參數a,函數調用function(1,2)調用處翻譯成匯編語言將變成:
            push 2      第二個參數入棧
            push 1      第一個參數入棧
            call function  調用參數,注意此時自動把cs:eip入棧
            而對于函數自身,則可以翻譯為: 
            push ebp     保存ebp寄存器,該寄存器將用來保存堆棧的棧頂指針,可以在函數退出時恢復
            mov ebp,esp  保存堆棧指針
            mov  eax,[ebp + 8H]  堆棧中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向a
            add eax,[ebp + 0CH]  堆棧中ebp + 12處保存了b
            mov  esp,ebp         恢復esp
            pop ebp
            ret 8
            而在編譯時,這個函數的名字被翻譯成_function@8 
            注意不同編譯器會插入自己的匯編代碼以提供編譯的通用性,但是大體代碼如此。其中在函數開始處保留esp到ebp中,在函數結束恢復是編譯器常用的方法。
            從函數調用看,2和1依次被push進堆棧,而在函數中又通過相對于ebp(即剛進函數時的堆棧指針)的偏移量存取參數。函數結束后,ret 8表示清理8個字節的堆棧,函數自己恢復了堆棧。

            c程序默認的是__cdecl
            __stdcall時輸入參數的棧空間有被調用函數恢復
            __cdecl時由調用函數恢復
            和參數如棧順序不同,記不清楚了

            是編譯器調用約定的一種 
            調用約定分為_cdecl _stdcall _fastcall thiscall naked  call等等 網絡上很多調用約定的介紹
             _stdcall將參數壓棧是按C語言的順序(從右到左),但與C 語言不同的是它是由被調用者將參數從棧中清除的,所以它的編譯文件比_cdecl?gt;>stdcall是Windows API函數中默認的調用約定,VB、VFP等也采用這個約定。 
               _cdecl是C語言采用的默認調用方法,它的優點是支持printf這樣的可變參數調用。 
              另外,VC++對于兩種調用方法的名稱轉換方法也不同
            ++++++++++++++++++++++++++++++++++++++++++++++++++++
            _stdcall  
            按 從右至左的順序壓參數入棧,由被調用者把參數彈出棧。對于“C”函數或者變量,修飾名以下劃線為前綴,然后是函數名,然后是符號“@”及參數的字節數,如 函數int  func(int  a,  double  b)的修飾名是_func@12。對于“C++”函數,則有所不同。   
            所有的Win32  API函數都遵循該約定。  
            +++++++++++++++++++++++++++++++++++++++++++++++++++++

            函數調用約定有多種,這里簡單說一下:
            1、__stdcall調用約定相當于16位動態庫中經常使用的PASCAL調用約定。在32 位的VC++5.0中PASCAL調用約定不再被支持(實際上它已被定義為__stdcall。除了__pascal外,__fortran和 __syscall也不被支持),取而代之的是__stdcall調用約定。兩者實質上是一致的,即函數的參數自右向左通過棧傳遞,被調用的函數在返回前 清理傳送參數的內存棧,但不同的是函數名的修飾部分(關于函數名的修飾部分在后面將詳細說明)。
            _stdcall是Pascal程序的缺省調用方式,通常用于Win32 Api中,函數采用從右到左的壓棧方式,自己在退出時清空堆棧。VC將函數編譯后會在函數名前面加上下劃線前綴,在函數名后加上"@"和參數的字節數。
            2、C調用約定(即用__cdecl關鍵字說明)按從右至左的順序壓參數入棧,由調用者把參數彈出棧。對于傳送參數的內存棧是由調用者來維護的(正因為如此,實現可變參數的函數只能使用該調用約定)。另外,在函數名修飾約定方面也有所不同。
            _cdecl是C和C++程序的缺省調用方式。每一個調用它的函數都包含清空堆棧的代碼,所以產生的可執行文件大小會比調用_stdcall函數的大。函數采用從右到左的壓棧方式。VC將函數編譯后會在函數名前面加上下劃線前綴。是MFC缺省調用約定。
            3、 __fastcall調用約定是"人"如其名,它的主要特點就是快,因為它是通過寄存器來傳送參數的(實際上,它用ECX和EDX傳送前兩個雙字 (DWORD)或更小的參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的內存棧),在函數名修飾約定方面,它和前兩者均不同。
            _fastcall方式的函數采用寄存器傳遞參數,VC將函數編譯后會在函數名前面加上"@"前綴,在函數名后加上"@"和參數的字節數。 
            4、thiscall僅僅應用于"C++"成員函數。this指針存放于CX寄存器,參數從右到左壓。thiscall不是關鍵詞,因此不能被程序員指定。
            5、naked call采用1-4的調用約定時,如果必要的話,進入函數時編譯器會產生代碼來保存ESI,EDI,EBX,EBP寄存器,退出函數時則產生代碼恢復這些寄存器的內容。
            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。
            posted on 2007-12-26 14:06 sdfasdf 閱讀(571) 評論(0)  編輯 收藏 引用
            久久亚洲精品国产精品婷婷| 一本色道久久88加勒比—综合| 国产精品一区二区久久精品涩爱| 亚洲综合久久夜AV | 久久久久中文字幕| 久久精品国产亚洲AV无码偷窥| 久久久久久狠狠丁香| 久久婷婷色综合一区二区| 久久精品无码一区二区三区| 久久久精品久久久久影院| 国产一区二区精品久久| 久久精品国产色蜜蜜麻豆| 久久97久久97精品免视看| 久久精品国产亚洲AV无码娇色 | 久久99精品免费一区二区| 一本一本久久a久久综合精品蜜桃| 国产一级持黄大片99久久| 色偷偷偷久久伊人大杳蕉| 久久综合久久伊人| 精品久久久久久无码中文字幕| 久久久久久无码Av成人影院| 国产精品成人久久久| 亚洲欧洲久久av| 午夜精品久久久久久久无码| 品成人欧美大片久久国产欧美| 久久精品人人做人人爽电影蜜月| 偷偷做久久久久网站| 久久婷婷五月综合色奶水99啪| 伊人久久五月天| 亚洲人成无码久久电影网站| 久久亚洲天堂| 色狠狠久久综合网| 伊人久久无码精品中文字幕| 久久综合鬼色88久久精品综合自在自线噜噜 | 香蕉久久一区二区不卡无毒影院| 精品久久久久久国产潘金莲| 精品无码久久久久国产| 久久久久久狠狠丁香| 久久久久无码中| 欧美久久久久久| 久久婷婷五月综合色奶水99啪|