C 學習第二天 根據彙編來理解物件導向指標的本質

2021-10-08 19:29:05 字數 1786 閱讀 4204

問題:指標是如何對物件導向裡的物件進行操作的呢

下面舉個例子

struct person 

};int main()

以下是通過c++語言反彙編的得到的組合語言

mov         dword ptr [ebp-14h],0ah  

mov dword ptr [ebp-10h],1

mov dword ptr [ebp-0ch],2

//不知道為啥在這又進行了一次位址操作我明明在c++沒有進行位址操作(已關掉編譯器優化)

lea ecx,[ebp-14h]

call 00ad1410

//從這裡往下是指標的操作

lea eax,[ebp-14h] //將物件所在的位址給eax

mov dword ptr [ebp-20h],eax //ebp-20h是指標所在的位址

mov eax,dword ptr [ebp-20h] //[ebp - 20h]是指標記憶體裡儲存的物件給eax

mov dword ptr [eax],14h //第乙個變數即物件所在的位址

mov eax,dword ptr [ebp-20h] //利用物件的位址 + 成員變數的偏移量計算出成員變數的位址

mov dword ptr [eax+4],2

mov eax,dword ptr [ebp-20h]

mov dword ptr [eax+8],2

mov ecx,dword ptr [ebp-20h]

call 00ad1410

``即原理就是

利用指標間接訪問所指向物件的成員的原理

1.從指標中取出物件的位址

2.利用物件的位址 + 成員變數的偏移量計算出成員變數的位址

3.根據成員變數的位址訪問成員變數的儲存空間

那麼問題又來了,如果我的指標直接

person *p = (person *) &person.m_height ;呢

p->m_age = 4;

p->m_height = 5;

p->run();

會列印什麼呢?

mov eax , [person.m_height]

lea [p] , eax

也就是說這時候p的位址是person._heigth的位址

如果編譯器還是按照位址訪問的話那麼由於位址已經比原來發生了變化

原age位址 = 現在age - 4 (int 是4個位元組)

也就是說先在age = 4 賦值 age所在的位址為原來m_height的位址

所有輸出結果應該是 4 5 cc

cc: 在彙編裡即int3 (中斷:interrupt) 起到斷點和中斷的作用

好處就是通過跳轉等 jmp 指令一不小心跳到這種棧空間會中斷

為什麼id為cc呢,是因為函式在呼叫的時候會生成乙個棧空間,在這個棧空間裡有可能剩下

上乙個函式呼叫棧空間沒有完全銷毀,即用cc填充

我們三個int 占用12 的記憶體 但是我們指標直接定位到第二個當作初始位置 並將位址傳給 this

所有編譯器按照我們的位址來 就會發現超出了

4+4+8

所以我們就出現了列印cc

C 學習第二天

方法的可選引數 static void main string args static void testinfo int a 158,int b 10,float f 0.8f b f a,b,f 下面這個方法中形式引數a為必選引數,換句話說當呼叫該方法時,至少是int a 118 testinf...

C 第二天學習

1.今天oj上開了 類 專題的題,做了幾個簡單的題,感覺上面的題還是比較水的,不過b題還是wa了4次。然後又看了一下課本上關於類的知識點,覺得類這種資料形式使資訊隱藏變得現實,只有類裡public下的函式可以使用private下的資料,如果沒有介面的話,這樣的乙個類就真的 隱藏 了。不過這樣就沒意義...

C 學習第二天

1.c語言的輸入輸出 define crt secure no warnings include include int main 2.c 的輸入和輸出 include include using namespace std void main 1.第乙個是我們 include他引用了沒有.h檔案這...