1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| int square(int num) { // 函数序言 square(int): push rbp mov rbp, rsp mov DWORD PTR [rbp-84], edi
int a = 100; mov DWORD PTR [rbp-68], 100
int *p = &a; lea rax, [rbp-68] mov QWORD PTR [rbp-8], rax
int *p2 = nullptr; mov QWORD PTR [rbp-16], 0
int *p3; // none
int &ref = a; lea rax, [rbp-68] mov QWORD PTR [rbp-24], rax
int b = ref; mov rax, QWORD PTR [rbp-24] mov eax, DWORD PTR [rax] mov DWORD PTR [rbp-28], eax
ref = 20; mov rax, QWORD PTR [rbp-24] mov DWORD PTR [rax], 20
*p = 20; mov rax, QWORD PTR [rbp-8] mov DWORD PTR [rax], 20
int c = a; mov eax, DWORD PTR [rbp-68] mov DWORD PTR [rbp-32], eax int d = *p; mov rax, QWORD PTR [rbp-8] mov eax, DWORD PTR [rax] mov DWORD PTR [rbp-36], eax
int &&r1 = 3; // 右值和左值一样也是指针地址,右值先做了拷贝,指向栈上 xvalue mov DWORD PTR [rbp-72], 3 lea rax, [rbp-72] mov QWORD PTR [rbp-48], rax int &&r2 = 10; mov DWORD PTR [rbp-76], 10 lea rax, [rbp-76] mov QWORD PTR [rbp-56], rax
// 取地址,拿值,进行拷贝 r2 = r1; mov rax, QWORD PTR [rbp-48] mov edx, DWORD PTR [rax] mov rax, QWORD PTR [rbp-56] mov DWORD PTR [rax], edx // 左值可以直接取值,进行拷贝 // 但右值引用无法用左值初始化,左值是直接拿值,那是bind的是右值,自相矛盾 // 否则所有权无法判断,因为右值要先取地址,相同的地址 r2 = a; mov edx, DWORD PTR [rbp-68] mov rax, QWORD PTR [rbp-56] mov DWORD PTR [rax], edx
// 直接拷贝了地址 int &&r3 = static_cast<int &&>(r1); mov rax, QWORD PTR [rbp-48] mov QWORD PTR [rbp-64], rax
// 总结:左值和右值,对于指针在汇编看来没有区别,但是指针不强制要求存地址,左右值强制要求存地址 // 右值会拷贝一次 xvalue,move 算法更像是改变的是编译器的限制 return 0; mov eax, 0 pop rbp ret }
|