从C++的标准可知,构造函数的返回值是一个新建立的对象的指针,即this指针。
/*
* 从汇编层面看,C++类(class)的组织方式和结构体数据完全一致。
*/
class c
{
private:
int v1;
int v2;
public:
c() {
v1 = 667;
v2 = 999;
}
c(int a, int b)
{
v1 = a;
v2 = b;
}
void dump() {
printf("%d, %d\n", v1, v2);
}
};
int main()
{
class c c1;
class c c2(5, 6);
c1.dump();
c2.dump();
return 0;
}
/* 反汇编 */
int main()
{
104b0: b580 push {r7, lr}
104b2: b084 sub sp, #16
104b4: af00 add r7, sp, #0
class c c1;
104b6: f107 0308 add.w r3, r7, #8 /* r3 = sp + 8, 存储对象c1的this指针 */
104ba: 4618 mov r0, r3 /* parameter 1 */
104bc: f000 f814 bl 104e8 <_ZN1cC1Ev> /* 调用构造函数 */
class c c2(5, 6);
104c0: 463b mov r3, r7 /* r3 = sp 存储对象c2的this指针 */
104c2: 2206 movs r2, #6 /* parameter 3 */
104c4: 2105 movs r1, #5 /* parameter 2 */
104c6: 4618 mov r0, r3 /* parameter 1 */
104c8: f000 f821 bl 1050e <_ZN1cC1Eii> /* 调用构造函数 */
c1.dump();
104cc: f107 0308 add.w r3, r7, #8 /* r3 = sp + 8 存储对象c1的this指针 */
104d0: 4618 mov r0, r3
104d2: f000 f82f bl 10534 <_ZN1c4dumpEv> /* c1调用dump */
c2.dump();
104d6: 463b mov r3, r7 /* r3 = sp */
104d8: 4618 mov r0, r3
104da: f000 f82b bl 10534 <_ZN1c4dumpEv> /* c2调用dump */
return 0;
104de: 2300 movs r3, #0
}
104e0: 4618 mov r0, r3
104e2: 3710 adds r7, #16
104e4: 46bd mov sp, r7
104e6: bd80 pop {r7, pc}
000104e8 <_ZN1cC1Ev>:
c() {
104e8: b480 push {r7}
104ea: b083 sub sp, #12
104ec: af00 add r7, sp, #0
104ee: 6078 str r0, [r7, #4] /* 构造函数返回的this指针 */
v1 = 667;
104f0: 687b ldr r3, [r7, #4]
104f2: f240 229b movw r2, #667 ; 0x29b
104f6: 601a str r2, [r3, #0] /* v1 = 667 */
v2 = 999;
104f8: 687b ldr r3, [r7, #4]
104fa: f240 32e7 movw r2, #999 ; 0x3e7
104fe: 605a str r2, [r3, #4] /* v2 = 999 */
}
10500: 687b ldr r3, [r7, #4]
10502: 4618 mov r0, r3 /* 返回值 */
10504: 370c adds r7, #12
10506: 46bd mov sp, r7
10508: f85d 7b04 ldr.w r7, [sp], #4
1050c: 4770 bx lr
0001050e <_ZN1cC1Eii>:
c(int a, int b)
1050e: b480 push {r7}
10510: b085 sub sp, #20
10512: af00 add r7, sp, #0
10514: 60f8 str r0, [r7, #12] /* 构造函数返回的this指针 */
10516: 60b9 str r1, [r7, #8] /* 参数 1 */
10518: 607a str r2, [r7, #4] /* 参数 2 */
v1 = a;
1051a: 68fb ldr r3, [r7, #12]
1051c: 68ba ldr r2, [r7, #8] /* a */
1051e: 601a str r2, [r3, #0] /* v1 = a */
v2 = b;
10520: 68fb ldr r3, [r7, #12]
10522: 687a ldr r2, [r7, #4] /* b */
10524: 605a str r2, [r3, #4] /* v2 = b */
}
10526: 68fb ldr r3, [r7, #12]
10528: 4618 mov r0, r3 /* 返回值 */
1052a: 3714 adds r7, #20
1052c: 46bd mov sp, r7
1052e: f85d 7b04 ldr.w r7, [sp], #4
10532: 4770 bx lr
00010534 <_ZN1c4dumpEv>:
void dump() {
10534: b580 push {r7, lr}
10536: b082 sub sp, #8
10538: af00 add r7, sp, #0
1053a: 6078 str r0, [r7, #4] /* this 指针 */
printf("%d, %d\n", v1, v2);
1053c: 687b ldr r3, [r7, #4]
1053e: 6819 ldr r1, [r3, #0] /* r1 = v1 */
10540: 687b ldr r3, [r7, #4]
10542: 685b ldr r3, [r3, #4] /* r3 = v2 */
10544: 461a mov r2, r3 /* r2 = v2 */
10546: f240 50a8 movw r0, #1448 ; 0x5a8 /* r0 = 0x5a8 */
1054a: f2c0 0001 movt r0, #1 /* r0 = (1 << 16) | 0x05a8 = 0x105a8 此为数据段地址 */
1054e: f7ff ef38 blx 103c0
}
10552: bf00 nop
10554: 3708 adds r7, #8
10556: 46bd mov sp, r7
10558: bd80 pop {r7, pc}