最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言三種函數(shù)調(diào)用約定_cdecl與_stdcall及_fastcall詳細(xì)講解

 更新時(shí)間:2022年10月19日 14:47:46   作者:是星星鴨  
本篇文章使用的工具是vs2010,內(nèi)容可能涉及到匯編的知識(shí),建議有一些匯編基礎(chǔ)的再來看,不過沒有匯編基礎(chǔ)也沒有關(guān)系,了解一下這三種調(diào)用約定即可

C語言常用的調(diào)用約定

以下就是C語言常用的三種調(diào)用約定:

調(diào)用約定參數(shù)壓棧順序平衡堆棧
__cdecl從右往左依次入棧調(diào)用者清理堆棧
__stdcall從右往左依次入棧自身清理堆棧
__fastcallECX/EDX傳遞前兩個(gè)參數(shù) 剩下的從右往左依次入棧自身清理堆棧

下面會(huì)舉例為大家講解三種調(diào)用約定的區(qū)別。

一、_cdecl調(diào)用約定

這是C語言默認(rèn)的調(diào)用約定,使用的平棧方式為外平棧

示例代碼:

以下代碼不使用任何調(diào)用約定,讓我們來看看函數(shù)默認(rèn)的調(diào)用約定是什么。

#include <stdio.h>
int method(int x,int y)
{
    return x+y;
}
int main()
{
    __asm mov eax,eax;    // 此處設(shè)置斷點(diǎn)
    method(1,2);
    return 0;
}

編譯、調(diào)試、ALT+8調(diào)出反匯編如下:

根據(jù)上面這張圖的描述,默認(rèn)的約定很符合__cdecl約定。

使用cdecl約定,如下:

vs2010:Ctrl+Alt+F7重新生成、F5調(diào)試、ALT+8查看反匯編:

一模一樣,可以看出__cdecl就是C語言默認(rèn)的調(diào)用約定。

二、_stdcall調(diào)用約定

和__cdecl一樣都是從右往左入棧參數(shù),不過該調(diào)用約定使用的平棧方式是內(nèi)平棧

示例代碼:

Ctrl+Alt+F7重新生成、F5調(diào)試、ALT+8查看反匯編:

可以看到,這里已經(jīng)看不到堆棧的處理了。

F11不斷執(zhí)行,直到進(jìn)入call指令調(diào)用的method函數(shù)中:

平棧操作跑到函數(shù)內(nèi)部了,__cdecl約定是調(diào)用者(main)函數(shù)進(jìn)行平棧,而__stdcall約定是函數(shù)內(nèi)部自身進(jìn)行平棧。

三、_fastcall調(diào)用約定

這是一個(gè)比較特殊的調(diào)用約定,當(dāng)函數(shù)參數(shù)為兩個(gè)或者以下時(shí),該約定的效率遠(yuǎn)遠(yuǎn)大于上面兩種,當(dāng)然隨著參數(shù)越來越多,該約定與上面兩種約定的差距逐漸縮小。

證明如下:

首先,我們使用__fastcall調(diào)用約定并傳入兩個(gè)參數(shù)。

重新生成、調(diào)試、匯編:

F11進(jìn)入函數(shù)內(nèi)部查看:

可以看出函數(shù)內(nèi)部和外部都沒有清理堆棧的操作。

這也就是__fastcall效率高的原因。

因?yàn)榧拇嫫骶褪菍儆赾pu的,然后堆棧是內(nèi)存,使用cpu進(jìn)行操作的效率肯定會(huì)大于使用內(nèi)存,所以我們使用寄存器的效率肯定比push傳參效率高很多啊。

那么為什么沒有平棧操作呢?

因?yàn)槲覀儧]有使用堆棧啊,我們只是用了寄存器,并沒有使用堆棧操作。

但是當(dāng)我們傳入更多的參數(shù)的時(shí)候就需要用到堆棧了,因?yàn)開_fastcall他只給我們提供了兩個(gè)寄存器ECX/EDX可以用來傳參。

四個(gè)參數(shù)試試:

重新生成、調(diào)試、匯編:

F11進(jìn)入函數(shù)內(nèi)部查看:

通過四個(gè)參數(shù)的傳遞,證明了:

函數(shù)參數(shù)除了前兩個(gè)參數(shù)使用寄存器、其他的依舊使用堆棧從右往左傳參,并且是自身清理堆棧,不是調(diào)用者清理。

思考為什么參數(shù)越來越多的時(shí)候,__fastcall與其他調(diào)用約定的差距越來越小呢?

答:首先我們知道了使用寄存器(cpu)的效率遠(yuǎn)遠(yuǎn)大于使用堆棧(內(nèi)存),然而__fastcall約定也只能使用兩個(gè)寄存器,當(dāng)函數(shù)參數(shù)只有兩個(gè)時(shí),__fastcall可以完全使用寄存器進(jìn)行函數(shù)傳參,所以這個(gè)時(shí)候他和__cdecl和__stdcall的差距最大。隨著參數(shù)越來越多,__fastcall依舊只能使用兩個(gè)寄存器,這樣一來參數(shù)越多,__fastcall使用內(nèi)存的占比就越大,所以性能差距也就越來越小。

總結(jié)

以上的內(nèi)容匯總?cè)缦拢?/p>

調(diào)用約定參數(shù)壓棧順序平衡堆棧調(diào)用約定特點(diǎn)
__cdecl從右往左依次入棧調(diào)用者清理堆棧這是C語言默認(rèn)的調(diào)用約定,使用的平棧方式為外平棧
__stdcall從右往左依次入棧自身清理堆棧和__cdecl一樣都是從右往左入棧參數(shù),不過該調(diào)用約定使用的平棧方式是內(nèi)平棧
__fastcallECX/EDX傳遞前兩個(gè)參數(shù) 剩下的從右往左依次入棧自身清理堆棧這是一個(gè)比較特殊的調(diào)用約定,當(dāng)函數(shù)參數(shù)為兩個(gè)或者以下時(shí),該約定的效率遠(yuǎn)遠(yuǎn)大于上面兩種,當(dāng)然隨著參數(shù)越來越多,該約定與上面兩種約定的差距逐漸縮小。

到此這篇關(guān)于C語言三種函數(shù)調(diào)用約定_cdecl與_stdcall及_fastcall詳細(xì)講解的文章就介紹到這了,更多相關(guān)C語言函數(shù)調(diào)用約定內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中進(jìn)行txt文件讀入和寫入的方法示例

    C++中進(jìn)行txt文件讀入和寫入的方法示例

    這篇文章主要給大家介紹了C++中進(jìn)行txt文件讀入和寫入的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • C++ 類this及返回自身對(duì)象的引用方式

    C++ 類this及返回自身對(duì)象的引用方式

    這篇文章主要介紹了C++ 類this及返回自身對(duì)象的引用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++內(nèi)存池兩種方案解析

    C++內(nèi)存池兩種方案解析

    這篇文章主要詳情介紹了C++內(nèi)存池兩種方案做對(duì)比,對(duì)此感興趣的小伙伴一起來看看吧
    2021-08-08
  • C 語言基礎(chǔ)教程(我的C之旅開始了)[九]

    C 語言基礎(chǔ)教程(我的C之旅開始了)[九]

    C 語言基礎(chǔ)教程(我的C之旅開始了)[九]...
    2007-02-02
  • C++利用類實(shí)現(xiàn)矩陣的數(shù)乘,乘法以及點(diǎn)乘

    C++利用類實(shí)現(xiàn)矩陣的數(shù)乘,乘法以及點(diǎn)乘

    這篇文章主要為大家詳細(xì)介紹了C++如何利用類實(shí)現(xiàn)矩陣的數(shù)乘,乘法以及點(diǎn)乘,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2022-11-11
  • C++利用ImGUI繪制D3D外部菜單

    C++利用ImGUI繪制D3D外部菜單

    ImGUI 它是與平臺(tái)無關(guān)的C++輕量級(jí)跨平臺(tái)圖形界面庫,沒有任何第三方依賴,可以將ImGUI的源碼直接加到項(xiàng)目中使用。本文將利用ImGUI繪制D3D外部菜單,需要的可以參考一下
    2022-09-09
  • C語言的分支和循環(huán)語句你了解嗎

    C語言的分支和循環(huán)語句你了解嗎

    這篇文章主要為大家詳細(xì)介紹了C語言的分支和循環(huán)語句,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • Qt中TCP協(xié)議通信詳解

    Qt中TCP協(xié)議通信詳解

    這篇文章主要為大家詳細(xì)介紹了Qt中TCP協(xié)議通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++多線程之帶返回值的線程處理函數(shù)解讀

    C++多線程之帶返回值的線程處理函數(shù)解讀

    這篇文章主要介紹了C++多線程之帶返回值的線程處理函數(shù)解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++實(shí)現(xiàn)求動(dòng)態(tài)矩陣各元素的和

    C++實(shí)現(xiàn)求動(dòng)態(tài)矩陣各元素的和

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)求動(dòng)態(tài)矩陣各元素的和,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10

最新評(píng)論

弥勒县| 班戈县| 广河县| 通榆县| 通州区| 讷河市| 洪湖市| 兴文县| 晴隆县| 延边| 合肥市| 福泉市| 彭州市| 得荣县| 威远县| 昌黎县| 洞头县| 泽普县| 交城县| 三亚市| 舞阳县| 兴隆县| 舟山市| 海原县| 来安县| 岗巴县| 浏阳市| 安国市| 商河县| 天镇县| 东源县| 嘉定区| 二连浩特市| 桓台县| 朔州市| 麻栗坡县| 璧山县| 凌源市| 息烽县| 平山县| 富阳市|