日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

用汇编的眼光看C++(之拷贝、赋值函数)

發布時間:2023/12/18 c/c++ 66 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用汇编的眼光看C++(之拷贝、赋值函数) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
拷貝構造函數和復制函數是類里面比較重要的兩個函數。兩者有什么區別呢?其實也很簡單,我們可以舉個例子,加入有這樣一個類的定義:

[cpp]?view plaincopy
  • class?apple??
  • {??
  • public:??
  • ????apple()?{??printf("apple()!\n");}??
  • ????apple(apple&?a)?{??printf("copy?apple()!\n");}??
  • ????apple&?operator=(apple&?a)?{??printf("=?apple()\n");?return?*this;}??
  • ????~apple()?{??printf("~apple()!\n");}??
  • ????void?print()?const?{??return;}??
  • };??
  • ?? ?那么我們在如下的函數里面進行調用的時候,調用的函數分別是哪些呢?

    [cpp]?view plaincopy
  • void?process()??
  • {??
  • ????apple?a,?c;??
  • ????apple?b?=a;??
  • ????c?=?b;??
  • }??
  • ?? ?其實匯編的結果是這樣的,大家可以一起看一下,自己嘗試讀一下。如果一次不是很明白,可以多讀幾次。

    [cpp]?view plaincopy
  • 70:???????apple?a,?c;??
  • 0040127D???lea?????????ecx,[ebp-10h]??
  • 00401280???call????????@ILT+70(apple::apple)?(0040104b)??
  • 00401285???mov?????????dword?ptr?[ebp-4],0??
  • 0040128C???lea?????????ecx,[ebp-14h]??
  • 0040128F???call????????@ILT+70(apple::apple)?(0040104b)??
  • 00401294???mov?????????byte?ptr?[ebp-4],1??
  • 71:???????apple?b?=a;??
  • 00401298???lea?????????eax,[ebp-10h]??
  • 0040129B???push????????eax??
  • 0040129C???lea?????????ecx,[ebp-18h]??
  • 0040129F???call????????@ILT+50(apple::apple)?(00401037)??
  • 004012A4???mov?????????byte?ptr?[ebp-4],2??
  • 72:???????c?=?b;??
  • 004012A8???lea?????????ecx,[ebp-18h]??
  • 004012AB???push????????ecx??
  • 004012AC???lea?????????ecx,[ebp-14h]??
  • 004012AF???call????????@ILT+75(apple::operator=)?(00401050)??
  • 73:???}??
  • 004012B4???mov?????????byte?ptr?[ebp-4],1??
  • 004012B8???lea?????????ecx,[ebp-18h]??
  • 004012BB???call????????@ILT+0(apple::~apple)?(00401005)??
  • 004012C0???mov?????????byte?ptr?[ebp-4],0??
  • 004012C4???lea?????????ecx,[ebp-14h]??
  • 004012C7???call????????@ILT+0(apple::~apple)?(00401005)??
  • 004012CC???mov?????????dword?ptr?[ebp-4],0FFFFFFFFh??
  • 004012D3???lea?????????ecx,[ebp-10h]??
  • 004012D6???call????????@ILT+0(apple::~apple)?(00401005)??
  • 004012DB???mov?????????ecx,dword?ptr?[ebp-0Ch]??
  • 004012DE???mov?????????dword?ptr?fs:[0],ecx??
  • 004012E5???pop?????????edi??
  • 004012E6???pop?????????esi??
  • 004012E7???pop?????????ebx??
  • 004012E8???add?????????esp,58h??
  • 004012EB???cmp?????????ebp,esp??
  • 004012ED???call????????__chkesp?(004087c0)??
  • 004012F2???mov?????????esp,ebp??
  • 004012F4???pop?????????ebp??
  • 004012F5???ret??
  • ?? ?代碼有點長,大家可以一句一句來看,比如說就按照70、71、72、73分別查看對應的匯編代碼:

    ?? ?(1)70句: 我們看到函數做了兩次函數調用,恰好就是apple的構造函數調用。這也正好對應著兩個臨時變量a和c,兩個變量的地址分別是【ebp-10】和【ebp-14】,這里也可以看出整個類的大小就是4個字節,就是一塊存放數據的普通內存。而構造函數之所以能和對應的內存綁定在一起,主要是因為ecx記錄了內存的起始地址,這在C++編譯中是十分關鍵的。我們看到的C++構造函數好像是沒有綁定內存,實際上在VC里面已經做好了約定,ecx就是this指針,就是類的內存起始地址。有興趣的同學看看G++編譯的時候,采用的this指針是哪個寄存器保存的?(其實是eax)

    ?? ?(2)71句:通過對應看到了eax記錄了引用變量的地址,而ecx是ebp下面緊挨著四個字節。但是函數調用的地址和前面的缺省構造函數不太一樣,所以我們大膽猜測,這里的構造函數這是拷貝構造函數,我們可以在調試的時候查看一下打印消息。

    ?? ?(3)72句:0x4012AF語句已經清楚地告訴了我們,這里調用的函數就是operator=函數,這一部分是算術符重載的內容,我們在后面的博客會重點介紹。

    ?? ?(4)73句: 前面我們講過,析構函數在函數調用結束的時候被被自動調用,那么這里我們看到卻是出現了三個調用?這三個變量正好是我們之前說的a、b、c三個變量。那么這三個變量調用的次序是怎樣的呢?我們可以查看一下變量的地址,分別是【ebp-18h】、【ebp-14h】、【ebp-10h】,這正好和變量出現的順序相反。所以我們看到,析構函數和構造函數是嚴格一一對應的,誰先出現,誰后析構。



    【預告: 下面的博客我們會對構造、析構中出現的一些現象進行總結】

    總結

    以上是生活随笔為你收集整理的用汇编的眼光看C++(之拷贝、赋值函数)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。