当前位置: 首页 > news >正文

从汇编的角度揭秘C++引用,豁然开朗

C++中的引用是指已有对象的别名,可以通过该别名访问并修改被引用的对象。那么其背后的原理是什么呢?引用是否会带来额外的开销呢?我们从一段代码入手,来分析一下引用的本质。

#include <stdio.h>
int main()
{int a = 10;int &b = a;b = 11;return 0;
} 

如上所示:定义了一个int型变量a,以及一个int型的引用b,并指向a。最后将b的值修改为11。

我们来看一下它对应的汇编代码:

      1  pushq   %rbp2  movq    %rsp, %rbp        //rbp = rsp 3  movl    $10, -12(%rbp)   //*(rbp-12) = 104  leaq    -12(%rbp), %rax  //rax = rbp - 125  movq    %rax, -8(%rbp)  //*(rbp - 8) = rax6  movq    -8(%rbp), %rax  //rax = *(rbp - 0x8)7  movl    $11, (%rax)     //*rax = 11;8  movl    $0, %eax9  popq    %rbp10  ret

我们来逐行分析:

先来介绍两个寄存器:

rsp:栈顶指针寄存器,rbp:栈基址指针寄存器。前两行push %rbp,以及move %rsp, %rbp。是保存函数调用之前的上下文信息,以及让rbp等于rsp。即此时main函数的栈空间是空的,这两条指令相当于main函数的准备工作。此时main函数的调用栈如下所示:

接下来:movl    $10, -12(%rbp),是将一个立即数写入rbp-12这个地址中,写入栈空间如下所示:

通过对比源代码,发现这条指令对应的是这行:int a = 10。接下来leaq    -12(%rbp), %rax,是将rbp-12的地址加载进rax, 即rax = rbp-12。也就是变量a的地址。接下来movq    %rax, -8(%rbp),即将rax(rax为rbp-12)写入rbp-8这个地址。执行完这条之后,栈上的分布如下:

即将rbp-12存入rbp-8这个地址中。rbp-12即是a的地址。这里其实就是引用的一个实现。接下来:movq    -8(%rbp), %rax,即将rbp-8地址里的内容(即rbp-12)赋值给rax, 即rax = rbp-12。接下来:movl    $11, (%rax) ,即将立即数11赋值给rax所指地址。rax为rbp-12, 那么rbp-12这个地址中的内容将被赋值为11。rbp-12即a的地址,那么执行完这条指令之后,a的值将被更新为11。栈上的分布如下:

对应源码即是b=11。此时,已经完成了通过引用将被引用对像值更新的过程。由此,我们可以看出,C++中引用实现的本质就是指针,即通过存储被引用对象的地址来实现。但是它比指针更加安全,可以认为是一个指针的语法糖。

此文对应的B栈视频如下:

用汇编揭秘C++引用的本质,豁然开朗_哔哩哔哩_bilibili

相关文章:

  • 【吾爱】逆向实战crackme160破解记录(三)
  • Generate Permutation
  • ALLEN BRADLEY特价型号1715-OB8DE 模块
  • Make All Equal
  • 灵活运用 NextJS 服务端组件与客户端组件
  • 远程终端登录和桌面访问(嵌入式开发)
  • 网络安全基础--第十天
  • 第十一章 注解
  • 【文献精读】Explaining grokking through circuit efficiency
  • 传输层协议:网络通信的关键纽带
  • Matlab自学笔记五十七:符号运算、可变精度运算、双精度浮点型运算,三种运算精度的概念、比较、选择和应用
  • 主线程极致优化:让CPU“零闲置“的实战方案
  • 制作一款打飞机游戏64:关卡设计
  • 推荐算法八股
  • LVS负载均衡
  • Java复习Day26
  • 线程相关面试题
  • JSCH使用SFTP详细教程
  • 【小红书】API接口,获取笔记列表
  • H.264编码
  • 个人作品网站策划书/百度搜索风云榜明星
  • 白云网站建设价格/网络营销文案策划
  • 中国排建设银行悦生活网站/新闻 最新消息
  • 手机网站自适应分辨率/系统优化的意义
  • 做透明头像的网站/qq营销推广方法和手段
  • 企业网站管理系统怎么用/aso网站