C++引用原理

杀马特。学长 韩版系。学妹 提交于 2020-08-10 23:29:27

1、直接定义引用变量

示例代码

#include<iostream>

void fun() {
	int a = 1;
	int& b = a;
	b = 10;
}

int main() {
	fun();
	return 0;
}

代码反汇编结果(使用VS反汇编,只看fun函数的代码即可)

#include<iostream>

void fun() {
00007FF7AAD01920  push        rdi  
00007FF7AAD01922  sub         rsp,40h  
00007FF7AAD01926  mov         rdi,rsp  
00007FF7AAD01929  mov         ecx,10h  
00007FF7AAD0192E  mov         eax,0CCCCCCCCh  
00007FF7AAD01933  rep stos    dword ptr [rdi]  

// 对变量a进行定义,a的地址为 rsp + 24h, 把这个地址的内容初始化为1
	int a = 1;
00007FF7AAD01935  mov         dword ptr [rsp+24h],1  
// 创建变量b,b是a的引用,b 是指向 a 的指针,变量b的地址为 rsp+38h
// lea         rax,[rsp+24h]   取得变量a的地址,并把地址放到rax寄存器中
// qword ptr [rsp+38h],rax 把rax的内容赋给变量b
	int& b = a;
00007FF7AAD0193D  lea         rax,[rsp+24h]  
00007FF7AAD01942  mov         qword ptr [rsp+38h],rax  

// 修改变量b的值的时候,首先取得b中的内容到寄存器中,然后以寄存器中的内容作为地址,修改对应地址的数据
// mov         rax,qword ptr [rsp+38h]  把 b 的值mov到rax寄存器中
// mov         dword ptr [rax],0Ah 把地址为rax的内存内容设置为 0AH(10)
	b = 10;
00007FF7AAD01947  mov         rax,qword ptr [rsp+38h]  
00007FF7AAD0194C  mov         dword ptr [rax],0Ah  
}
00007FF7AAD01952  mov         rcx,rsp  
00007FF7AAD01955  lea         rdx,[00007FF7AAD09E30h]  
00007FF7AAD0195C  call        00007FF7AAD01221  
00007FF7AAD01961  add         rsp,40h  
00007FF7AAD01965  pop         rdi  
00007FF7AAD01966  ret  

2、方法参数传引用

示例代码

#include<iostream>

void fun(int &a) {
	a = 10;
}

int main() {
	int a = 1;
	fun(a);

	std::cout << a << std::endl;
	return 0;
}

代码反汇编结果(从main函数看起)

#include<iostream>

void fun(int &a) {
// 把 rsp+8 地址的内容设置为寄存器 rcx 中的内容(rcx为请求参数,内容为main函数中定义的变量a的地址)
00007FF746531470  mov         qword ptr [rsp+8],rcx  
00007FF746531475  push        rdi  
// 执行代码 a = 10;  首先取得 rsp+10h 中的值,然后以 rsp+10h 中的值作为地址修改对应内存中的数据
	a = 10;
00007FF746531476  mov         rax,qword ptr [rsp+10h]  
00007FF74653147B  mov         dword ptr [rax],0Ah  
}
00007FF746531481  pop         rdi  
00007FF746531482  ret  

// 中间省略一堆垃圾代码

int main() {
00007FF746531490  push        rdi  
00007FF746531492  sub         rsp,40h  
00007FF746531496  mov         rdi,rsp  
00007FF746531499  mov         ecx,10h  
00007FF74653149E  mov         eax,0CCCCCCCCh  
00007FF7465314A3  rep stos    dword ptr [rdi]  
// 定义变量a,并把a的值初始化为1, a的地址为 rsp+24h
	int a = 1;
00007FF7465314A5  mov         dword ptr [rsp+24h],1  
// 调用 fun函数,由于参数较少,因此此函数调用使用寄存器传参
// lea         rcx,[rsp+24h]  把rcx寄存器的值设置为参数的a的地址
// 使用call指令调用 fun 函数
	fun(a);
00007FF7465314AD  lea         rcx,[rsp+24h]  
00007FF7465314B2  call        00007FF74653107D  
	std::cout << a << std::endl;
00007FF7465314B7  mov         edx,dword ptr [rsp+24h]  
00007FF7465314BB  mov         rcx,qword ptr [00007FF74653E170h]  
00007FF7465314C2  call        qword ptr [00007FF74653E158h]  
00007FF7465314C8  lea         rdx,[00007FF74653108Ch]  
00007FF7465314CF  mov         rcx,rax  
00007FF7465314D2  call        qword ptr [00007FF74653E160h]  
	return 0;
00007FF7465314D8  xor         eax,eax  
}
00007FF7465314DA  mov         edi,eax  
00007FF7465314DC  mov         rcx,rsp  
00007FF7465314DF  lea         rdx,[00007FF746539E40h]  
00007FF7465314E6  call        00007FF7465311F9  
00007FF7465314EB  mov         eax,edi  
00007FF7465314ED  add         rsp,40h  
00007FF7465314F1  pop         rdi  
00007FF7465314F2  ret  

总结

C ++ 中的引用和指针并无本质区别,就只是编译器自动对指针做了取值操作而已

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!