從這部分開始我們除了利用內(nèi)存的信息打印來進行探索外,更多的會通過跟蹤和觀察編譯器產(chǎn)生的匯編代碼來理解編譯器對這些語言特性的實現(xiàn)方式。匯編方面知識的討論超出了本文的范圍,我只對和我們討論相關(guān)的匯編代碼進行解析。理解本文要討論的知識并不需要有很完整的匯編知識,但必須了解起碼的概念。
下面我們看看引入虛繼承后的影響。為了有所對比我們首先看看普通成員函數(shù)的調(diào)用情況。
執(zhí)行如下代碼,它包括了對象的普通成員函數(shù)調(diào)用,類的靜態(tài)成員函數(shù)調(diào)用、通過指針調(diào)用普通成員函數(shù):
結(jié)果如下:
這是obj對象的內(nèi)存地址。
首先我們看看對象的普通成員函數(shù)調(diào)用,obj.foo();,對應(yīng)的匯編代碼為:
第1行把對象的地址存入ecx寄存器,執(zhí)行完這行指令后,我們要以看到ecx中的值為0x0012F843,就是前面打印出的值。如果函數(shù)需要傳遞參數(shù),我們還會在前面看到一些push指令。在第2行我們可以看到call的是一個直接的地址,這也就是靜態(tài)綁定。即函數(shù)的調(diào)用地址在編譯時已經(jīng)被編譯器決議。
跟蹤進去我們要以看到是一條跳轉(zhuǎn)指令,繼續(xù)執(zhí)行可以看到真正的函數(shù)代碼部分,如下(注:為了討論方便我在第行前面加了一個行號):
我們看看第7行,把ecx寄存器入棧,后面4行初始化了函數(shù)的堆棧中的保存局部變量的部分。第12行彈出ecx值,到這里時ecx的值保持為在函數(shù)調(diào)用前存入的對象內(nèi)存地址,第13行就是保存this指針的值,作為一個局部變量。這樣我們就知道了VC7.1不是象傳遞普通函數(shù)那樣通過壓棧來傳遞this 指針,而是通過ecx寄存器來傳遞。第14、15行利用這個this指針給對象的成員變量進行了賦值。
再看看靜態(tài)成員函數(shù)調(diào)用的匯編代碼:
非常直接,因為它不需要處理this指針,跟蹤到函數(shù)的匯編代碼,可以看到同樣不需要處理this指針。具體的代碼這里就不列出來了。
再看看通過指針調(diào)用普通成員函數(shù)pt-》 foo();,產(chǎn)生的匯編代碼如下:
和通過對象調(diào)用普通成員函數(shù)的代碼差不多。不過存對象地址到ecx寄存器地,是通過解引用pt指針來找到對象地址的。
-
寄存器
+關(guān)注
關(guān)注
31文章
5421瀏覽量
123308 -
打印
+關(guān)注
關(guān)注
1文章
66瀏覽量
18945 -
編譯器
+關(guān)注
關(guān)注
1文章
1654瀏覽量
49886
發(fā)布評論請先 登錄
C++ 多繼承類 虛基類分享
什么是繼承?
虛電路,虛電路的特點,虛電路的原理是什么?
虛短和虛斷概念剖解及應(yīng)用實例
手機該不該ROOT權(quán)限?ROOT之后會怎樣?
PCBA加工中造成虛焊的原因及解決方法
一文詳解虛函數(shù)及其相關(guān)知識點
怎樣在Java中實現(xiàn)多繼承
什么是虛焊假焊?造成虛焊假焊的原因有哪些?
為什么運放會有虛短虛斷?
造成虛焊、假焊的原因有哪些?如何預(yù)防虛焊假焊

評論