从汇编代码学习C++语言2—类复制构造函数
类的复制构造函数同样是C++类的重要函数。
Code 1没有复制构造函数,我们将从汇编代码分析:
class Object
{
public:
Object()
{
code1 = 10;
code2 = 5;
}
~Object()
{
code1 = 0;
code2 = 0;
}
int code1;
int code2;
};
void func(int a, Object b, int c) //This place will call copy constructor
{
a = 84;
c = 84;
b.code1 = 84;
}
int main(int argc, char *argv[])
{
int i = 0;
Object c;
Object d = c; //This place will call copy constructor
func(1, c, 2);
return 0;
}
汇编代码如下:
Disassembly of section .text:
00000000 <__Z4funci6Objecti>:
int code1;
int code2;
};
void func(int a, Object b, int c)
{
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp //Assign 16Bytes stack memory
a = 84;
6: c7 45 fc 54 00 00 00 movl $0x54,-0x4(%ebp) //Assign 84 to ebp - 4Byte
c = 84;
d: c7 45 f8 54 00 00 00 movl $0x54,-0x8(%ebp) //Assign 84 to ebp - 8Byte
b.code1 = 84;
14: 8b 45 0c mov 0xc(%ebp),%eax //Assign 84 to ebp + 12Bytes (ebp + 8 is a, ebp + 12 is address of b)
17: c7 00 54 00 00 00 movl $0x54,(%eax)
}
1d: c9 leave
1e: c3 ret
0000001f <_main>:
int main(int argc, char *argv[])
{
1f: 55 push %ebp
20: 89 e5 mov %esp,%ebp
22: 53 push %ebx
23: 83 e4 f0 and $0xfffffff0,%esp
26: 83 ec 30 sub $0x30,%esp
29: e8 00 00 00 00 call 2e <_main+0xf>
int i = 0;
2e: c7 44 24 2c 00 00 00 movl $0x0,0x2c(%esp) //Assign zero to esp + 44Bytes
35: 00
Object c;
36: 8d 44 24 1c lea 0x1c(%esp),%eax //Get address esp + 28 to eax
3a: 89 04 24 mov %eax,(%esp) //Assign eax to esp
3d: e8 00 00 00 00 call 42 <_main+0x23> //Call Object constructor
Object d = c;
42: 8b 44 24 1c mov 0x1c(%esp),%eax //get address esp + 28 to eax,
46: 89 44 24 14 mov %eax,0x14(%esp) //Let esp + 20 point to esp + 28
4a: 8b 44 24 20 mov 0x20(%esp),%eax //get address esp + 32 to eax
4e: 89 44 24 18 mov %eax,0x18(%esp) //let esp + 24 point to esp + 32,
//Note there is none copy constructor, so just do this way.
func(1, c, 2);
52: 8b 44 24 1c mov 0x1c(%esp),%eax //get address esp + 28 to eax
56: 89 44 24 24 mov %eax,0x24(%esp) //let esp + 36 point esp + 28
5a: 8b 44 24 20 mov 0x20(%esp),%eax //get address esp + 32 to eax
5e: 89 44 24 28 mov %eax,0x28(%esp) //let esp + 40 point to esp + 32
62: c7 44 24 08 02 00 00 movl $0x2,0x8(%esp) //assign 2 to esp + 8
69: 00
6a: 8d 44 24 24 lea 0x24(%esp),%eax //get address esp + 36 to eax
6e: 89 44 24 04 mov %eax,0x4(%esp) //let esp + 4 point to esp + 36,
//esp + 28 is the address of object c;
72: c7 04 24 01 00 00 00 movl $0x1,(%esp) //assign 2 to esp
79: e8 82 ff ff ff call 0 <__Z4funci6Objecti> //call func
7e: 8d 44 24 24 lea 0x24(%esp),%eax //get address esp + 36 to eax
82: 89 04 24 mov %eax,(%esp) //assign esp + 36 to esp
85: e8 00 00 00 00 call 8a <_main+0x6b> //call deconstructor
return 0;
8a: bb 00 00 00 00 mov $0x0,%ebx
}
Disassembly of section .text$_ZN6ObjectC1Ev:
00000000 <__ZN6ObjectC1Ev>:
class Object
{
public:
Object()
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
{
code1 = 10;
3: 8b 45 08 mov 0x8(%ebp),%eax
6: c7 00 0a 00 00 00 movl $0xa,(%eax)
code2 = 5;
c: 8b 45 08 mov 0x8(%ebp),%eax
f: c7 40 04 05 00 00 00 movl $0x5,0x4(%eax)
}
16: 5d pop %ebp
17: c3 ret
Disassembly of section .text$_ZN6ObjectD1Ev:
00000000 <__ZN6ObjectD1Ev>:
~Object()
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
{
code1 = 0;
3: 8b 45 08 mov 0x8(%ebp),%eax
6: c7 00 00 00 00 00 movl $0x0,(%eax)
code2 = 0;
c: 8b 45 08 mov 0x8(%ebp),%eax
f: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax)
}
16: 5d pop %ebp
17: c3 ret
add copy constructor into code 2:
#include <cstdio>
class Object
{
public:
Object()
{
code1 = 10;
code2 = 5;
}
Object(Object& o)
{
code1 = o.code1;s
}
~Object()
{
code1 = 0;
code2 = 0;
}
int code1;
int code2;
};
void func(int a, Object b, int c)
{
a = 84;
c = 84;
b.code1 = 84;
}
int main(int argc, char *argv[])
{
int i = 0;
Object c;
Object d = c;
func(1, c, 2);
return 0;
}
Assembly codes list following:
int main(int argc, char *argv[])
{
1f: 55 push %ebp
20: 89 e5 mov %esp,%ebp
22: 53 push %ebx
23: 83 e4 f0 and $0xfffffff0,%esp
26: 83 ec 30 sub $0x30,%esp
29: e8 00 00 00 00 call 2e <_main+0xf>
int i = 0;
2e: c7 44 24 2c 00 00 00 movl $0x0,0x2c(%esp)
35: 00
Object c;
36: 8d 44 24 1c lea 0x1c(%esp),%eax
3a: 89 04 24 mov %eax,(%esp)
3d: e8 00 00 00 00 call 42 <_main+0x23> //Call constructor
Object d = c;
42: 8d 44 24 1c lea 0x1c(%esp),%eax
46: 89 44 24 04 mov %eax,0x4(%esp)
4a: 8d 44 24 14 lea 0x14(%esp),%eax
4e: 89 04 24 mov %eax,(%esp)
51: e8 00 00 00 00 call 56 <_main+0x37> //Call copy constructor
func(1, c, 2);
56: 8d 44 24 1c lea 0x1c(%esp),%eax
5a: 89 44 24 04 mov %eax,0x4(%esp)
5e: 8d 44 24 24 lea 0x24(%esp),%eax
62: 89 04 24 mov %eax,(%esp)
65: e8 00 00 00 00 call 6a <_main+0x4b> //Call copy constructor again
6a: c7 44 24 08 02 00 00 movl $0x2,0x8(%esp)
71: 00
72: 8d 44 24 24 lea 0x24(%esp),%eax
76: 89 44 24 04 mov %eax,0x4(%esp)
7a: c7 04 24 01 00 00 00 movl $0x1,(%esp)
81: e8 7a ff ff ff call 0 <__Z4funci6Objecti> //Call deconstructor
86: 8d 44 24 24 lea 0x24(%esp),%eax
8a: 89 04 24 mov %eax,(%esp)
8d: e8 00 00 00 00 call 92 <_main+0x73>
return 0;
92: bb 00 00 00 00 mov $0x0,%ebx
}
Disassembly of section .text$_ZN6ObjectC1Ev:
00000000 <__ZN6ObjectC1Ev>:
#include <cstdio>
class Object
{
00000000 <__ZN6ObjectC1ERS_>:
Object(Object& o)
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
{
code1 = o.code1;
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 8b 10 mov (%eax),%edx
8: 8b 45 08 mov 0x8(%ebp),%eax
b: 89 10 mov %edx,(%eax)
}
d: 5d pop %ebp
e: c3 ret
f: 90 nop
}