前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C++对象模型_Class Obj作为函数参数

C++对象模型_Class Obj作为函数参数

作者头像
chinchao.xyz
发布2022-04-25 15:20:01
发布2022-04-25 15:20:01
1.2K00
代码可运行
举报
文章被收录于专栏:k8s快速入门k8s快速入门
运行总次数:0
代码可运行
开发环境
  • VC6.0
  • 编辑器 Cmd Markdown
  1. 关于C/C++中基本类型(如:int,int*等)作为函数参数时,是通过将该变量的值压栈来进行参数传递;本文通过C++反汇编代码分析了当对象作为函数参数时(该形参非引用或指针),参数如何传递以及此时栈帧的结构。
  2. 对象作为函数参数时,参数传递过程(如:函数的声明为:void show(class Object obj);该函数的调用的为show(arg);其中实参arg的类型为class Object):1,在栈顶上为obj对象分配内存空间,然后将对象arg的首地址压栈;2,调用拷贝构造函数(此为C++中三种调用拷贝构造函数情况之一),将arg的数据成员拷贝至obj;3,执行show()函数体(此时,ebp+8即为obj的首地址)。
  3. 具体分析过程,见代码注释。
代码语言:javascript
代码运行次数:0
运行
复制
//C++源码。
//VC6.0
#include<iostream>
#includestdio>
using namespace std;
class CBase{
 int i;
public:
 CBase(int i=0)
 {
  this->i=i;
 }
 CBase(CBase& rhs) //拷贝构造函数。
 {
  i=rhs.i;
  printf("拷贝构造函数=%d\n",i);
 }
 void show(CBase B1, CBase B2) //对象作为形参。
 {
  printf("show=%d,%d\n",B1.i,B2.i);
 }
};
int main()
{
 CBase Base;
 CBase Basex(1);
 CBase Basexx(2);
 Base.show(Basex,Basexx);
// printf("this is an end!\n");
}
---------------------------------------------------------------------------------
//main函数对应的汇编代码。
 int main()
24: {
0040D4A0 push ebp
0040D4A1 mov ebp,esp
0040D4A3 sub esp,54h
0040D4A6 push ebx
0040D4A7 push esi
0040D4A8 push edi
0040D4A9 lea edi,[ebp-54h]
0040D4AC mov ecx,15h
0040D4B1 mov eax,0CCCCCCCCh
0040D4B6 rep stos dword ptr [edi]
25: CBase Base;
0040D4B8 push 0
0040D4BA lea ecx,[ebp-4] //ecx保存的是对象Base的this指针。
0040D4BD call @ILT+0(CBase::CBase) (00401005)//调用构造函数
26: CBase Basex(1);
0040D4C2 push 1
0040D4C4 lea ecx,[ebp-8] //ecx保存的是对象Basex的this指针。
0040D4C7 call @ILT+0(CBase::CBase) (00401005)//调用构造函数
27: CBase Basexx(2);
0040D4CC push 2
0040D4CE lea ecx,[ebp-0Ch] //ecx保存的是对象Basexx的this指针。
0040D4D1 call @ILT+0(CBase::CBase) (00401005)//调用构造函数
28: Base.show(Basex,Basexx);
0040D4D6 push ecx //等价于esp=esp-4;
0040D4D7 mov ecx,esp //ecx保存的是show函数的形参B2的this指针。
0040D4D9 lea eax,[ebp-0Ch]
0040D4DC push eax //对Basexx的this(即Basexx对象的首地址)指针压栈。
0040D4DD call @ILT+10(CBase::CBase) (0040100f)//调用拷贝构造函数
0040D4E2 push ecx //等价于esp=esp-4;
0040D4E3 mov ecx,esp //ecx保存的是show函数的形参B1的this指针。
0040D4E5 lea edx,[ebp-8]
0040D4E8 push edx //对Basex的this(即Basex对象的首地址)指针压栈。
0040D4E9 call @ILT+10(CBase::CBase) (0040100f)//调用拷贝构造函数
0040D4EE lea ecx,[ebp-4] //ecx保存的是Base对象的this指针。
0040D4F1 call @ILT+20(CBase::show) (00401019)//调用show函数。
29: printf("this is an end!\n");
0040D4F6 push offset string "this is an end!\n" (00422fa4)
0040D4FB call printf (0040d7c0)
0040D500 add esp,4
30: }
0040D503 pop edi
0040D504 pop esi
0040D505 pop ebx
0040D506 add esp,54h
0040D509 cmp ebp,esp
0040D50B call __chkesp (004010b0)
0040D510 mov esp,ebp
0040D512 pop ebp
0040D513 ret
//show函数对应的汇编代码。
16: void show(CBase B1,CBase B2)
17: {
0040D550 push ebp
0040D551 mov ebp,esp
0040D553 sub esp,44h
0040D556 push ebx
0040D557 push esi
0040D558 push edi
0040D559 push ecx
0040D55A lea edi,[ebp-44h]
0040D55D mov ecx,11h
0040D562 mov eax,0CCCCCCCCh
0040D567 rep stos dword ptr [edi]
0040D569 pop ecx
0040D56A mov dword ptr [ebp-4],ecx
18: printf("show=%d,%d\n",B1.i,B2.i);
0040D56D mov eax,dword ptr [ebp+0Ch] //ebp+0Ch对应的是B2的首地址。
0040D570 push eax
0040D571 mov ecx,dword ptr [ebp+8] //ebp+8h对应的是B1的首地址。
0040D574 push ecx
0040D575 push offset string "show=%d,%d\n" (00422fcc)
0040D57A call printf (0040d7c0)
0040D57F add esp,0Ch
19: }
0040D582 pop edi
0040D583 pop esi
0040D584 pop ebx
0040D585 add esp,44h
0040D588 cmp ebp,esp
0040D58A call __chkesp (004010b0)
0040D58F mov esp,ebp
0040D591 pop ebp
0040D592 ret 8
//拷贝构造函数对应的汇编代码(注释略)。
11: CBase(CBase& rhs)
0040D840 push ebp
0040D841 mov ebp,esp
0040D843 sub esp,44h
0040D846 push ebx
0040D847 push esi
0040D848 push edi
0040D849 push ecx
0040D84A lea edi,[ebp-44h]
0040D84D mov ecx,11h
0040D852 mov eax,0CCCCCCCCh
0040D857 rep stos dword ptr [edi]
0040D859 pop ecx
0040D85A mov dword ptr [ebp-4],ecx
12: {
13: i=rhs.i;
0040D85D mov eax,dword ptr [ebp-4]
0040D860 mov ecx,dword ptr [ebp+8]
0040D863 mov edx,dword ptr [ecx]
0040D865 mov dword ptr [eax],edx
14: printf("拷贝构造函数=%d\n",i);
0040D867 mov eax,dword ptr [ebp-4]
0040D86A mov ecx,dword ptr [eax]
0040D86C push ecx
0040D86D push offset string "\xbf\xbd\xb1\xb4\xb9\xb9\xd4\xec\xba\xaf\xca\xfd=%d\n" (00422fb8)
0040D872 call printf (0040d7c0)
0040D877 add esp,8
15: }
0040D87A mov eax,dword ptr [ebp-4]
0040D87D pop edi
0040D87E pop esi
0040D87F pop ebx
0040D880 add esp,44h
0040D883 cmp ebp,esp
0040D885 call __chkesp (004010b0)
0040D88A mov esp,ebp
0040D88C pop ebp
0040D88D ret 4
  1. 当执行show函数作用域内代码时,栈结构图示如下:
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开发环境
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档