從彙編看c++中引用與指標的流量分析

來源:互聯網
上載者:User

首先是引用情形下的c++源碼:

複製代碼 代碼如下:void add(int a, int b, int&c) {
c = a + b;
}

int main() {
int a = 1;
int b = 2;
int c = 0;
add(a, b, c);

}

下面是main對應的彙編碼:
複製代碼 代碼如下:; 6 : int main() {

push ebp
mov ebp, esp
sub esp, 12 ; 為該調用函數的棧空間預留12byte,用來儲存局部變數a,b, c

; 7 : int a = 1;

mov DWORD PTR _a$[ebp], 1;初始化a _a$為a儲存空間地址相對於ebp基址的位移量

; 8 : int b = 2;

mov DWORD PTR _b$[ebp], 2;初始化b _b$為b儲存空間地址相對於ebp基址的位移量

; 9 : int c = 0;

mov DWORD PTR _c$[ebp], 0;初試化c _c$為c儲存空間地址相對於ebp基址的位移量

; 10 : add(a, b, c);
lea eax, DWORD PTR _c$[ebp]; 擷取c儲存空間相對於ebp基址的位移量(即c儲存單元的位移地址),放在寄存器eax中
push eax;儲存c儲存空間的位移量到堆棧中
mov ecx, DWORD PTR _b$[ebp];將b儲存空間裡面的值(即b的值)放在寄存器ecx中
push ecx;儲存b儲存空間的值到堆棧中
mov edx, DWORD PTR _a$[ebp];將a儲存空間裡面的值(即a的值)放在寄存器edx裡面
push edx;儲存a儲存空間的到堆棧

;上面push eax push ecx push edx在棧裡面儲存了原來局部變數a,b,c的值,只不過對於c來說,儲存的是c儲存空間的位移地址
;因此,對於a,b來說,也就是將他們的值得一份拷貝存了起來,也就是傳值;而c只是儲存了自己儲存空間的位移地址,也就是傳地址
call ?add@@YAXHHAAH@Z ; 調用add函數,上面的語句已經為傳遞參數做好了準備
add esp, 12 ; 由於剛才為調用函數add傳遞參數進行了壓棧,這裡釋放棧空間,即釋放參數
;這就是為什麼函數調用完成後局部變數和參數無效的原因,因為他們的空間被釋放了

; 11 :
; 12 : }

xor eax, eax
mov esp, ebp
pop ebp
ret 0

下面是函數add對應的彙編碼:
複製代碼 代碼如下:; 1 : void add(int a, int b, int&c) {

push ebp
mov ebp, esp

; 2 : c = a + b;

mov eax, DWORD PTR _a$[ebp];取參數a的值到寄存器eax中
add eax, DWORD PTR _b$[ebp];取參數b的值與eax中a的值相加,結果放到eax中
mov ecx, DWORD PTR _c$[ebp];去c的位移地址放到寄存器ecx中
mov DWORD PTR [ecx], eax;將eax中的結果寫到由ecx指定的地址單元中去,即c所在儲存單元

; 3 : }

pop ebp
ret 0

從上面可以看到,對於傳值,c++確實傳的是一份值拷貝,而對於引用,雖然是傳值的形式,但是其實編譯器內部傳遞的是值得地址

下面是指標的情形的c++源碼:

複製代碼 代碼如下:void add(int a, int b, int* c) {
*c = a + b;
}

int main() {
int a = 1;
int b = 2;
int c = 0;
add(a, b, &c);

}

mian函數對應的彙編碼:
複製代碼 代碼如下:; 6 : int main() {

push ebp
mov ebp, esp
sub esp, 12 ;

; 7 : int a = 1;

mov DWORD PTR _a$[ebp], 1

; 8 : int b = 2;

mov DWORD PTR _b$[ebp], 2

; 9 : int c = 0;

mov DWORD PTR _c$[ebp], 0

; 10 : add(a, b, &c);

lea eax, DWORD PTR _c$[ebp]
push eax
mov ecx, DWORD PTR _b$[ebp]
push ecx
mov edx, DWORD PTR _a$[ebp]
push edx
call ?add@@YAXHHPAH@Z ; add
add esp, 12 ;
; 11 :
; 12 : }

xor eax, eax
mov esp, ebp
pop ebp
ret 0

add函數對應的彙編碼:
複製代碼 代碼如下:; 1 : void add(int a, int b, int* c) {

push ebp
mov ebp, esp

; 2 : *c = a + b;

mov eax, DWORD PTR _a$[ebp]
add eax, DWORD PTR _b$[ebp]
mov ecx, DWORD PTR _c$[ebp]
mov DWORD PTR [ecx], eax

; 3 : }

pop ebp
ret 0

可以看到,指標和引用的彙編碼一樣,因此兩者的作用也一樣

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.