簡體   English   中英

指令集如何區分參考值

[英]How do instruction sets differentiate value from reference

讓我們看一下這段代碼:

int main ()
{
    int a = 5;
    int&b = a;

    cout << a << endl;  // 5 is displayed
    cout << b << endl;  // 5 is also displayed

    return 0;
}

這是我在調試器中看到的行為。

int a = 5將在內存地址-0x14(%rbp)中分配值5

int& b = a將分配值-0x14(%rbp)在存儲器地址-0x8(%RBP)

當我cout << a << endl ,將顯示a地址(即-0x14(%rbp))中的值。

但是以某種方式,當我執行cout << b << endl ,確定b地址中的值(即-0x8(%rbp) )是一個地址,然后顯示該地址的值( -0x14(%rbp) ) 。

這是std :: cout調用的程序集:

20                  cout << a << endl;
0000000000401506:   mov -0xc(%rbp),%eax
0000000000401509:   mov %eax,%edx
000000000040150b:   lea 0x6f8c9c6e(%rip),%rcx        # 0x6fccb180 <libstdc++-6!_ZSt4cout>
0000000000401512:   callq 0x4015f8 <_ZNSolsEi>
0000000000401517:   lea 0xe2(%rip),%rdx        # 0x401600 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_>
000000000040151e:   mov %rax,%rcx
0000000000401521:   callq 0x401608 <_ZNSolsEPFRSoS_E>
21                  cout << b << endl;
0000000000401526:   mov -0x8(%rbp),%rax
000000000040152a:   mov (%rax),%eax
000000000040152c:   mov %eax,%edx
000000000040152e:   lea 0x6f8c9c4b(%rip),%rcx        # 0x6fccb180 <libstdc++-6!_ZSt4cout>
0000000000401535:   callq 0x4015f8 <_ZNSolsEi>
000000000040153a:   lea 0xbf(%rip),%rdx        # 0x401600 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_>
0000000000401541:   mov %rax,%rcx
0000000000401544:   callq 0x401608 <_ZNSolsEPFRSoS_E>
24                  return 0;

題:

兩條std :: cout指令都非常相似, ab有何區別?

簡而言之:事實並非如此。

CPU本身並不關心哪種類型存儲在哪里,它只執行編譯器生成的指令。

編譯器知道b是一個引用,而不是int 因此,它指示CPU將b視為指針。

如果查看程序的匯編代碼,則會看到訪問ab的指令是不同的: b的部分包含一條額外的指令。

mov (%rax),%eax

這是取消引用的步驟。 (在該匯編符號中,括號表示取消引用,因此此指令含義類似於eax = * rax)。

我想您絕對沒有要求優化。 盡管即使那樣,我仍希望訪問ab來生成完全相同的代碼(至少在這種情況下)。

關於編譯器如何知道: ab具有不同的類型,因此編譯器知道對它們執行不同的操作。 該標准經過精心設計,可以用int& int* const替換int& ,然后在每次訪問時自動取消引用(初始化除外)將產生符合要求的實現; 看起來這就是您的編譯器正在執行的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM