成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

函數調用的三種約定,你都清楚嗎

開發 后端
三種調用方式的區別相信大家應該有些了解,這篇文章主要從實例和匯編的角度闡述這些區別的表現形態,使其對它們的區別認識從理論向實際過渡。

 __cdecl、__stdcall、__fastcall是C/C++里中經常見到的三種函數調用方式。其中__cdecl是C/C++默認的調用方式,__stdcall是windows API函數的調用方式,只不過我們在頭文件里查看這些API的聲明的時候是用了WINAPI的宏進行代替了,而這個宏其實就是__stdcall了。

三種調用方式的區別相信大家應該有些了解,這篇文章主要從實例和匯編的角度闡述這些區別的表現形態,使其對它們的區別認識從理論向實際過渡。

我們知道,函數的調用過程是通過函數棧幀的不斷變化實現的:

函數的調用,涉及參數傳遞,返回值傳遞,調用后返回,這都是通過棧的變化來實現的,對于三種調用約定而言:

__cdecl:

C/C++默認方式,參數從右向左入棧,主調函數負責棧平衡。

__stdcall:

windows API默認方式,參數從右向左入棧,被調函數負責棧平衡。

__fastcall:

快速調用方式。所謂快速,這種方式選擇將參數優先從寄存器傳入(ECX和EDX),剩下的參數再從右向左從棧傳入。因為棧是位于內存的區域,而寄存器位于CPU內,故存取方式快于內存,故其名曰“__fastcall”。

下面從實例來認識一下這三種調用約定。先來看一個簡單的不能再簡單的程序了:

 

三個函數的內容都是一樣的,不同的是使用了三種調用的方式。我們先來看看在main函數調用三個函數的時候的匯編代碼: 

按照上面說的那樣,__cdecl按照參數從右向左的方式進入棧區,注意Fun1()和Fun3()的區別,Fun1()在call Fun1()之后執行了add esp,8。這一操作正是我們前面所說的進行棧的平衡。調用函數之前連續進行了兩次push操作將函數所需的實參5和2先后壓入了棧區,調用完成后,我們需要恢復調用前的狀態,則需調整棧頂指針esp的位置,這一工作由誰來完成就決定了兩種函數調用方式__cdecl(主調函數完成)和__stdcall(被調函數完成)的區別。上圖我們看到了__cdecl中由主調函數完成了,那么__stdcall呢,在被調函數Fun3()中,轉向被調函數結尾處的代碼,我們看到了這一句:

那么Fun1()結尾處又是如何呢?

看到了吧,這個ret指令后面跟沒跟值就決定了函數返回是棧指針ESP需要增加的量。這樣,不需要主調函數再調用add指令為ESP操作平衡棧區,節約了程序的開銷,一條指令開銷小,如果十萬百萬個這樣的調用,這個開銷就明顯了。

說完了__cdecl和__stdcall,再來看看__fastcall,如前面圖看到的調用時并未使用push指令向棧里傳參數,而是使用了

  mov  edx, 5

  mov  ecx, 2

兩條指令。這樣直接將參數傳入寄存器,被調函數在執行的時候直接從寄存器取值即可,省去了從棧里取出來給寄存器,再從寄存器取出來放入內存。

不過,說個題外話,ecx寄存器經常作為計數和C++里this指針的傳遞媒介。在這種情況下,情況又是怎樣的呢,下次分析C++操作符 new 的時候再予以討論。ecx做計數器時,需要將ecx中存儲的實參先壓入棧區,計數操作完成后再pop出來。如此一來,這個fastcall倒顯得不那么fast了。

當然,上面所說的這些操作都是由編譯器在背后為我們完成的,開發人員無需關心這些操作,對我們是透明的。不過,知其然更知其所以然方能立于不敗之地! 

 

責任編輯:龐桂玉 來源: C語言與C++編程
相關推薦

2019-05-08 10:50:37

交換機組網網絡

2021-09-13 13:05:05

Redis數據庫內存

2023-02-27 23:45:09

MySQL索引存儲

2023-08-04 08:25:03

客戶配置Spring

2023-09-22 08:01:10

2023-09-14 23:14:57

MySQL索引

2021-02-25 23:40:26

Redis集群架構

2023-02-02 14:24:08

物聯網數據分析云平臺

2021-10-10 12:29:27

機器人AI人工智能

2011-01-18 15:35:59

jQueryJavaScriptweb

2022-01-10 07:57:25

Linux 插樁Linux 系統

2022-07-09 15:37:14

數字化轉型企業數字化

2020-09-11 06:39:29

ThreadLocal線程

2024-11-26 07:47:41

2024-05-27 00:20:00

2024-08-13 08:25:16

C#外部程序方式

2025-06-06 00:00:00

JavaHTTPMCP

2021-07-10 10:01:37

Python簡單函數

2021-03-17 09:59:26

Python函數調用

2024-04-11 12:57:55

Python函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久国产精品免费一区二区三区 | 国产1区2区3区 | 免费国产黄 | 久在线视频 | 久久五月婷| 性色视频在线观看 | 日韩精品久久久久 | 成人自拍视频网站 | 一区二区三区四区不卡 | 国产福利精品一区 | 高清av一区| 国产成人综合在线 | 97久久精品午夜一区二区 | 久久久久久成人 | 91精品国产色综合久久不卡98 | 日韩精品一区二区三区在线 | 国产精品视频一区二区三区四蜜臂 | 亚洲a在线观看 | 一级欧美 | 亚洲天堂中文字幕 | 天久久| 亚洲福利网 | 日日摸日日碰夜夜爽2015电影 | 伊人伊人伊人 | 国产精品久久久久久久久久久久 | 国产91丝袜在线播放 | 国产二区精品视频 | 欧美a在线 | 免费成人高清在线视频 | 久久噜噜噜精品国产亚洲综合 | 99re| 欧美日韩中文字幕 | 在线免费观看视频黄 | 日韩在线免费视频 | 亚洲中午字幕 | 天天爱天天操 | 一级黄色片美国 | 日韩波多野结衣 | www.国产精品 | 午夜免费福利片 | 精品av天堂毛片久久久借种 |