64,648
社区成员
发帖
与我相关
我的任务
分享
//C++代码:
#include<iostream>
using namespace std;
class A
{
public:
A(int x = 0) : a(x){cout<<"normal"<<endl;}
A(const A &ref) : a(ref.a){cout<<"copy"<<endl;}
int a;
};
void test(A x)
{
}
int main()
{
A a;
test(a);
system("pause");
return 0;
}
//汇编代码:
17: int main()
18: {
004011B0 push ebp
004011B1 mov ebp,esp
004011B3 sub esp,48h
004011B6 push ebx
004011B7 push esi
004011B8 push edi
004011B9 lea edi,[ebp-48h]
004011BC mov ecx,12h
004011C1 mov eax,0CCCCCCCCh
004011C6 rep stos dword ptr [edi]
19: A a;
004011C8 push 0
004011CA lea ecx,[ebp-4] //ecx传递this指针?
004011CD call @ILT+10(A::A) (0040100f) //构造局部对象a
20:
21: test(a);
004011D2 push ecx //传递拷贝构造函数的引用参数 即对象a的地址
004011D3 mov ecx,esp //这条语句是干嘛的? 为形参分配空间?
004011D5 lea eax,[ebp-4]
004011D8 push eax //这条语句的作用是什么? 构造形参的话this指针有了,参数也有了,怎么此处又将a的地址入栈?
004011D9 call @ILT+150(A::A) (0040109b) //在ecx指向的空间以已经压栈的a的地址做引用参数拷贝构造形参?
004011DE call @ILT+180(test) (004010b9) //
004011E3 add esp,4
22: system("pause");
004011E6 push offset string "pause" (0043101c)
004011EB call system (00409140)
004011F0 add esp,4
23: return 0;
004011F3 xor eax,eax
24: }
13: void test(A x)
14: {
00401180 push ebp
00401181 mov ebp,esp
00401183 sub esp,40h
00401186 push ebx
00401187 push esi
00401188 push edi
00401189 lea edi,[ebp-40h]
0040118C mov ecx,10h
00401191 mov eax,0CCCCCCCCh
00401196 rep stos dword ptr [edi]
15: }
00401198 pop edi
00401199 pop esi
0040119A pop ebx
0040119B mov esp,ebp
0040119D pop ebp
0040119E ret
004011D2 push ecx ;将ecx入栈保存
004011D8 push eax ;a作为参数入栈,调用A的拷贝构造函数,
;在esp-4~esp处生成一个临时对象
19: A a;
004011C8 push 0 ;实际要调用A(int x = 0)这个构造函数,
;这个是默认参数入栈
004011CA lea ecx,[ebp-4] ;将a对象的地址存入ecx,vc一般this存入ecx
;gcc中this作为最后一参数入栈的,显然ebp-4 ~ebp这段空间就是a的存储空间
004011CD call @ILT+10(A::A) (0040100f) //构造局部对象a
20:
21: test(a);
004011D2 push ecx ;将ecx入栈保存
004011D3 mov ecx,esp ;将esp保存到ecx,说明编译器打算将esp-4~esp
;作为test函数中参数a对应的内存,test传参时要调用A的拷贝构造函数生成一个临时对象
004011D5 lea eax,[ebp-4];将a的地址保存eax
004011D8 push eax ;a作为参数入栈,调用A的拷贝构造函数,
;在esp-4~esp处生成一个临时对象
004011D9 call @ILT+150(A::A) (0040109b)
004011DE call @ILT+180(test) (004010b9) ;由于在上个栈帧顶端esp-4~esp已经生成了一个
;一个临时对象a,所以省去了push操作,直接调用test函数
004011E3 add esp,4
22: system("pause");
004011E6 push offset string "pause" (0043101c)
004011EB call system (00409140)
004011F0 add esp,4
23: return 0;
004011F3 xor eax,eax
24: }
004011D8 push eax //这条语句的作用是什么? 构造形参的话this指针有了,参数也有了,怎么此处又将a的地址入栈?
//esp 1-----------1
// 1 &a 1 -->004011D8 push,eax //此处为拷贝构造函数的参数
// 1-----------1
// 1 &a 1 -->004011D2 push,ecx //此处创建形参 里面为什么要存储&a呢?只开辟空间就够了 莫非只是简单的使栈往上增长(move ecx,esp)开辟空间存放形参?
// 1-----------1
// 1 1
// 1 . 1
// 1 . 1
// 1 . 1
// 1 . 1
// 1 1
// 1 1
// 1-----------1
// 1 局部对象a 1
// 1-----------1 -->ebp