从汇编的角度揭开C++ this指针的神秘面纱(下)

<接上篇>

我们接着来看一段C++的代码:

class A
{
public:int func(int j){return j +_i;}
private:int _i;    
};int main()
{A a;a.func(3);return 0;
}

这里定义了一个类A,在main函数中定义了A类的对像a。同时用a调用了成员函数func。我们来看一下main函数的汇编代码:

        pushq   %rbpmovq    %rsp, %rbpsubq    $16, %rsp         //rsp = rsp - 16leaq    -4(%rbp), %rax    //rax = rpb -4movl    $3, %esi          //esi = 3movq    %rax, %rdi        //rdi = raxcall    A::func(int)movl    $0, %eaxleaveret

在调用A::func之前,赋值了两个寄存器:rdi和rsi. 由上篇文单可知,这两个寄存器用于函数调用时,传递第1和第2个参数。那么这里我们有疑问:A::func(int)明明只有一个参数,为什么调用时,传递了两个参数呢?另一个参数是什么呢?答案就是:在调用成员函数时,this指针会做为一个隐含的参数传递给成员函数,并且是作为第一个参数。那么this指针又代表什么呢,this指针就是指向类对象的一个地址。对应上面汇编代码即是rbp-4。源代码a.func(3)相当于func(this, 3)也就是func(&a, 3); 

为了方便理解,我画出了main函数的栈空间,如下所示:

this指针存储的是a对象的地址。即rbp-4. 此时a对象里面只有一个int型的成员变量i, 占用4个字节。

接下来,我们分析一下func函数,汇编如下:

A::func(int):pushq   %rbpmovq    %rsp, %rbpmovq    %rdi, -8(%rbp)      //*(rbp-8) = rdimovl    %esi, -12(%rbp)     // *(rbp-12) = esimovq    -8(%rbp), %rax      // rax = *(rbp-8) movl    (%rax), %edx        // edx = *raxmovl    -12(%rbp), %eax     // eax = *(rbp-12)addl    %edx, %eax          // eax += edxpopq    %rbpret

func函数栈空间如下:  

  

func中会先分配栈空间rbp-8, rbp-12来存储传递过来的参数rdi(this)以及esi(3)。 然后根据这些参数来做下一步处理。

总结:

1)this指针的本质即对象的地址。

2)在调用类成员函数时,C++编译器会将其作为函数的第一个参数,传递给成员函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/909798.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/909798.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka代码模板

Kafka 服务器&#xff08;Broker&#xff09; 的配置 server.properties # broker.id: 每个 Kafka Broker 的唯一标识符。broker.id 必须在整个 Kafka 集群中唯一。 broker.id0# 配置 Kafka Broker 监听客户端请求的地址和端口。这个配置决定了 Kafka 服务将接受来自生产者、…

最大子数组和C++

给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输出&#xff1a;…

centos 7单机安装ceph并创建rbd块设备

1. 安装依赖包 新增阿里云源ceph下载地址 vim /etc/yum.repos.d/ceph.repo [ceph] nameceph baseurlhttp://mirrors.aliyun.com/ceph/rpm-jewel/el7/x86_64/ gpgcheck0 [ceph-noarch] namecephnoarch baseurlhttp://mirrors.aliyun.com/ceph/rpm-jewel/el7/noarch/ gpgcheck…

Jenkins搭建、权限管理、参数化、流水线等详细教程!

部署Jenkins 一、jenkins 安装 官网&#xff1a; https://jenkins.io yum 安装 jenkins *jenkins 依赖 java 环境 #注意2.346之后的版本不再支持jdk8 卸载旧jenkins #查询以前是否安装jenkins rpm -qa |grep jenkins #卸载 jenkins yum -y remove jenkins rpm -e jenkins…

百度飞桨(PaddlePaddle)案例分享:基于 PaddleOCR 的图像文字提取系统

一、案例背景 在实际教学、办公及政务系统中&#xff0c;纸质材料&#xff08;如手写作文、表格、试卷等&#xff09;仍广泛存在。为提升信息处理效率&#xff0c;采用 OCR&#xff08;Optical Character Recognition&#xff09;技术将图像中的文字提取为可编辑文本已成为刚需…

python操控鼠标

在已知屏幕坐标的情况下&#xff0c;可以通过 Python 的 pyautogui 或 pynput 等库实现网页上的鼠标点击操作。以下是具体步骤和代码示例&#xff1a; 1. 使用 PyAutoGUI&#xff08;推荐&#xff09; pyautogui 是一个简单易用的库&#xff0c;可以直接通过屏幕坐标控制鼠标点…

UV 与 Bun 深度解析

UV 与 Bun 深度解析&#xff1a;现代开发工具的安装与使用指南 什么是 UV&#xff1f; UV&#xff08;Ultra-Velocity&#xff09;是由 Astral 公司&#xff08;Ruff 的创建者&#xff09;开发的超高速 Python 包管理工具&#xff1a; 用 Rust 编写&#xff0c;速度极快&…

【算力网络】多样化算力感知

一、算力网络 ​ 算力网络&#xff08;Computing Power Network&#xff09;是我国率先提出的原创性技术理念&#xff0c;其核心是通过高速网络整合分散的算力资源&#xff08;如云端、边缘、终端等&#xff09;&#xff0c;实现算力的动态感知、智能调度和一体化服务&#x…

Greenplum/PostgreSQL pg_hba.conf 认证方法详解

Greenplum/PostgreSQL pg_hba.conf 认证方法详解 pg_hba.conf 文件中的 METHOD 字段指定了客户端认证方式&#xff0c;以下是各种认证方法的详细说明和配置示例。 常用认证方法 1. trust - 无条件允许连接 说明&#xff1a;不需要密码&#xff0c;完全信任连接 适用场景&am…

分布式数据库中间件-Sharding-JDBC

前言 学习视频&#xff1a;深入Sharding-JDBC分库分表从入门到精通【黑马程序员】本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除 1、概述 1.1、分库分表是什么 小明是一家初创电商平台的开发人员&#xff0c;他负责卖家模块的功能开发&#xff0c;其中…

pycharm2020.2版本给项目选择了虚拟环境解释器,项目文件都运行正常,为什么terminal文件路径的前面没有虚拟解释器的名称

解决问题&#xff1a; 1.打开 Anaconda Prompt输入 conda init cmd.exe 或者 pycharm终端直接 conda init cmd.exe 重启动 CMD和pycharm&#xff0c;使配置生效。

2025商旅平台排行:国内主流商旅平台解析

在数字化转型加速2025年&#xff0c;企业商旅管理正从“成本中心”向“智能管控枢纽”升级。如何通过技术赋能实现商旅成本精准优化与管理效率跃升&#xff1f;本文聚焦国内五大主流商旅平台&#xff0c;以“综合型头部平台创新型平台”双维度解析&#xff0c;结合数据实证与场…

CNS无线电信号覆盖分析系统v0.1

#系统终端有的版本号了# 开发一套类EMACS的专业软件任重道远&#xff0c;经过慢吞吞的开发&#xff0c;我们已经将目标定位大幅下调了&#xff0c;不再对标EMACS系统了&#xff0c;改为瞄行业老二WRAP软件了。当然WRAP软件在电磁信号仿真分析领域也是神一样的存在&#xff0c;其…

单视频二维码生成与列表二维码生成(完整版)

视频二维码有有两种情况&#xff1a;一种是单个视频的生成一个二维码&#xff1b;另一种是一组视频&#xff08;多个视频&#xff09;生成一个列表二维码。用户按自己的实际需求生成&#xff0c;即可&#xff0c;很方便。 STEP1 注册帐号 使用视频二维码&#xff0c;您需要注…

关于linux:1. Linux 基础运维

一、Linux 安装与发行版选择 关于操作系统种类&#xff1a; 1&#xff09;基于 Linux 内核的操作系统 Ubuntu、Debian、Kali、CentOS、RHEL、Arch、Android、Alpine、OpenWRT 等 特点&#xff1a;开源、稳定、安全、广泛使用于服务器与开发领域 2&#xff09;基于 Windows…

(LeetCode 每日一题) 2016. 增量元素之间的最大差值 (数组)

题目&#xff1a;2016. 增量元素之间的最大差值 思路&#xff1a;维护已遍历过的最小值&#xff0c;时间复杂度0(n)。 C版本&#xff1a; class Solution { public:int maximumDifference(vector<int>& nums) {int mnnums[0];int ans0;for(int i1;i<nums.size()…

MySQL基础与常用数据类型浅析

一.MySQL数据类型分类 二.数值类型 2.1int类型 我们使用TINYINT作为例子进行实验验证: 越界插入会直接报错,跟我们当时学习语言的时候不太一样,语言会进行隐式类型转换或截断.一般不会直接报错.其他的int类型也是同理. 说明: 在MySQL中&#xff0c;整型可以指定是有符号的…

Ubuntu 20.04离线安装Nvidia-docker

服务器因系统故障重装&#xff0c;安装docker容器时发现几年前的在线安装步骤不好使了&#xff0c;只好尝试离线安装。为了下次不卡壳&#xff0c;记录一下安装步骤。 先确定自己的操作系统&#xff0c;并确保已经安装了nvidia driver。我的操作系统是Ubuntu 20.04。 1. 下载…

6,TCP客户端

1,创建一个新的项目 2,界面设计

【dify更新问题】如何更新dify且低成本解决git pull 443问题

我的dify部署在mini server上&#xff0c;挂不了TZ&#xff0c;所以采用了如下办法 更新origin (.git/config) 地址为&#xff1a;https://gitee.com/dify_ai/dify.git 顺序执行 &#xff08;https://docs.dify.ai/en/getting-started/install-self-hosted/docker-compose#upg…