c++中引用是通过指针的方式实现

发布于:2024-09-18 ⋅ 阅读:(12) ⋅ 点赞:(0)

其实在汇编层面上,引用的代码和指针的代码是一致的。

先看指针情况下的代码分析,如下所示:

#include <iostream>

using namespace std;

void fuzhi(int *x)//引用传参 
{
	*x = 10;
}

int main(int argc, char** argv)
{
	int a = 0;
	int b;
	a = 20;

	fuzhi(&a);

	return 0;
}

本人用的是vs2017编译器,先打断点如下:
在这里插入图片描述
注意本人打断点的位置,然后启动调试,然后打开反汇编窗口,如下图所示:
在这里插入图片描述

这里面的截图不清晰,本人现在只截右边汇编窗口的部分,如下所示:

可以看到,红色方框圈里来的有两部分,其中第一部分是栈帧大小的圈定,bp是栈底,sp是栈顶,由于栈是自顶向下生长,所以sp其实比bp小。里面的0DCh,其中字母h表示16进制,故0DCh是十进制的220,这就是目前main函数栈帧的大小,如果main函数中定义一个数组char szBuf[1000],则会发现这里面的0DCh要变成一个比较大的数字,肯定比1000大。
在这里插入图片描述

再看第二部分,这一部分其实是对栈帧空间进行初始化,初始化用到的数字就是0xCCCCCCCC。初始化的范围为37h(0x37),即55个四字节大小。共220个字节,现在调试下看看,鼠标放到汇编代码出,按F10执行下一步,F11是step in。
在这里插入图片描述

可以看到esp的值是17823592,变量a的值是7940691,16进制表示为0x792A53,esp的16进制表示为0x10FF768,然后打开内存窗口,输入0x10FF768
在这里插入图片描述
红色部分框住的就是a的值,可以看到cpu是小端模式,然后汇编代码接着F10,过初始化后,可以看到内存窗口大部分区域被初始化成了cc。此时a的值就是0xCCCCCCCC,很明显是一个负数,a = -858993460。
在这里插入图片描述

栈帧构建和初始化就讲到这里,后面看fuzhi(&a)处的汇编代码

fuzhi(&a);
007921B0  lea         eax,[a]  
007921B3  push        eax  
007921B4  call        fuzhi (079140Bh)  
007921B9  add         esp,4  

第一步,lea eax,[a]是指将a的地址赋给eax,第二部push eax,这步是参数压栈,而eax目前的值是a的地址,故压栈的参数就是a的地址。

如下所示:
在这里插入图片描述

F10到call这步,可以看到eax的值是17823808,16进制是10FF840,即a的地址。
然后按F11,进入到fuzhi函数的汇编代码处。
在这里插入图片描述
红色部分的3部分,第一部分是栈帧大小的开辟,第二部分是栈帧数据的初始化,第三部分是首先将x的值赋给eax,然后将0Ah,即数字10,赋给eax所指的内存单元,即x所指的内存单元。所以函数调用后,变量的值自然改变。

下面再看下引用代码的情况,代码如下:

#include <iostream>

using namespace std;

void fuzhi(int &x)//引用传参 
{
	x = 10;
}

int main(int argc, char** argv)
{
	int a = 0;
	int b;
	a = 20;

	fuzhi(a);

	return 0;
}

如前面一样打断点,查看右边的汇编代码:
在这里插入图片描述
可以看到前面也是栈帧开辟和初始化,现在看main调用fuzhi这块调用汇编代码:

	fuzhi(a);
007B21B0  lea         eax,[a]  
007B21B3  push        eax  
007B21B4  call        fuzhi (07B1410h)  
007B21B9  add         esp,4 

可以看出跟前面指针代码时的一摸一样。

然后调试到fuzhi代码的汇编处,可以看到,也是将10赋值给x的地址空间。

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到