反汇编 之C++类

56 篇文章 0 订阅

#include <stdio.h>

/*
 * 从汇编层面看,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;
}

#if 0

为什么这些函数有这些奇怪的名字?
其实这是编译器对函数名称进行改编(name mangling)的结果。

名称改编是一种在编译过程中,用ASCII字符串将函数、变量的名称重新改编的机制。
改编后的方法(类成员函数)名称就被用作该程序内部的函数名。这完全是因为编译器
Linker和加载DLL的OS装载器均不能识别C++或OOP(面向对象的变成语言)的数据结构。


构造函数本身就是一种函数,它们使用ECX存储结构体的指针,然后将指针复制到其自己
的局部变量里。当然,第二步不是必须的。

从C++的标准可知,构造函数的返回值是一个新建立的对象的指针,即this指针。

/*
 * intel
 */

0000000000001169 <main>:
    1169:    f3 0f 1e fa              endbr64
    116d:    55                       push   %rbp                // rsp=rsp-8, rsp=rbp ===> subq $8,%rsp, movq %rbp,(%rsp)
    116e:    48 89 e5                 mov    %rsp,%rbp        // rbp=rsp
    1171:    48 83 ec 20              sub    $0x20,%rsp        // rsp = rsp-0x20
    1175:    64 48 8b 04 25 28 00     mov    %fs:0x28,%rax    // 把fs的偏移值x28放入rax
                                                            // 指向特定于线程或定义的结构
                                                            // %fs:0x28主要是用来起sentinel(哨兵)的作用,
    117c:    00 00
    117e:    48 89 45 f8              mov    %rax,-0x8(%rbp)    // 防止overflow的,即使用了8字节进行安全保护
    1182:    31 c0                    xor    %eax,%eax        // eax 清零
    1184:    48 8d 45 e8              lea    -0x18(%rbp),%rax    // rax = rbp-0x18 = c1 = this
    1188:    48 89 c7                 mov    %rax,%rdi        // rdi = rax
    118b:    e8 4a 00 00 00           callq  11da <_ZN1cC1Ev>    // _ZN1cC1Ev(rdi)
    1190:    48 8d 45 f0              lea    -0x10(%rbp),%rax    // rax = rpb-0x10 = c2 = this
    1194:    ba 06 00 00 00           mov    $0x6,%edx        // edx = 6
    1199:    be 05 00 00 00           mov    $0x5,%esi        // esi = 5
    119e:    48 89 c7                 mov    %rax,%rdi        // rdi = rax
    11a1:    e8 58 00 00 00           callq  11fe <_ZN1cC1Eii>    // _ZN1cC1Eii(rdi, esi, edx)
    11a6:    48 8d 45 e8              lea    -0x18(%rbp),%rax    // rax = c1 = this
    11aa:    48 89 c7                 mov    %rax,%rdi        // rdi = rax
    11ad:    e8 74 00 00 00           callq  1226 <_ZN1c4dumpEv>    // _ZN1c4dumpEv(rdi)
    11b2:    48 8d 45 f0              lea    -0x10(%rbp),%rax        // rax = c2 = this
    11b6:    48 89 c7                 mov    %rax,%rdi            // rdi = rax
    11b9:    e8 68 00 00 00           callq  1226 <_ZN1c4dumpEv>    // _ZN1c4dumpEv(rdi)
    11be:    b8 00 00 00 00           mov    $0x0,%eax            // eax = 0
    11c3:    48 8b 4d f8              mov    -0x8(%rbp),%rcx    // 防止overflow
    11c7:    64 48 33 0c 25 28 00     xor    %fs:0x28,%rcx    // fs:0x28 = 0
    11ce:    00 00
    11d0:    74 05                    je     11d7 <main+0x6e>    // 上面xor指令结果为零,执行正常退出,否则溢出检测失败报错
    11d2:    e8 89 fe ff ff           callq  1060 <__stack_chk_fail@plt>    // 溢出检测
    11d7:    c9                       leaveq                    // ===> mov %rbp,%rsp, pop %rbp
    11d8:    c3                       retq                    // ===> pop %rip
    11d9:    90                       nop

00000000000011da <_ZN1cC1Ev>:
    11da:    f3 0f 1e fa              endbr64
    11de:    55                       push   %rbp                // rsp=rsp-8, rsp=rbp ===> subq $8,%rsp, movq %rbp,(%rsp)
    11df:    48 89 e5                 mov    %rsp,%rbp        // rbp=rsp
    11e2:    48 89 7d f8              mov    %rdi,-0x8(%rbp)    // rbp-0x8 = rdi
    11e6:    48 8b 45 f8              mov    -0x8(%rbp),%rax    // rax = rbp-0x8 = rdi
    11ea:    c7 00 9b 02 00 00        movl   $0x29b,(%rax)    // rax = 0x29b = 667
    11f0:    48 8b 45 f8              mov    -0x8(%rbp),%rax    // rax = rbp-0x8 = rdi
    11f4:    c7 40 04 e7 03 00 00     movl   $0x3e7,0x4(%rax)    // rax+4 = 0x3e7 = 999
    11fb:    90                       nop
    11fc:    5d                       pop    %rbp                // rbp=rsp, rsp+8 ===> movq %rsp,(%rbp), addq $8, (%rsp)
    11fd:    c3                       retq                    // ===> pop %rip

00000000000011fe <_ZN1cC1Eii>:
    11fe:    f3 0f 1e fa              endbr64
    1202:    55                       push   %rbp                // rsp=rsp-8, rsp=rbp ===> subq $8,%rsp, movq %rbp,(%rsp)
    1203:    48 89 e5                 mov    %rsp,%rbp        // rbp=rsp
    1206:    48 89 7d f8              mov    %rdi,-0x8(%rbp)    // rbp-0x8 = rdi = this
    120a:    89 75 f4                 mov    %esi,-0xc(%rbp)    // rbp-0xc = esi = 5
    120d:    89 55 f0                 mov    %edx,-0x10(%rbp)    // rpb-0x10 = edx = 6
    1210:    48 8b 45 f8              mov    -0x8(%rbp),%rax    // rax = this
    1214:    8b 55 f4                 mov    -0xc(%rbp),%edx    // edx = 5
    1217:    89 10                    mov    %edx,(%rax)        // rax = 5        ===> this.v1 = 5
    1219:    48 8b 45 f8              mov    -0x8(%rbp),%rax    // rax = this
    121d:    8b 55 f0                 mov    -0x10(%rbp),%edx    // edx = 6
    1220:    89 50 04                 mov    %edx,0x4(%rax)    // rax+0x4 = 6    ===> this.v2 = 6
    1223:    90                       nop
    1224:    5d                       pop    %rbp                // rbp=rsp, rsp+8 ===> movq %rsp,(%rbp), addq $8, (%rsp)
    1225:    c3                       retq                    // ===> pop %rip

0000000000001226 <_ZN1c4dumpEv>:
    1226:    f3 0f 1e fa              endbr64
    122a:    55                       push   %rbp                // rsp=rsp-8, rsp=rbp ===> subq $8,%rsp, movq %rbp,(%rsp)
    122b:    48 89 e5                 mov    %rsp,%rbp        // rbp=rsp
    122e:    48 83 ec 10              sub    $0x10,%rsp        // rsp = rsp-0x10
    1232:    48 89 7d f8              mov    %rdi,-0x8(%rbp)    // rbp-0x8 = rdi = this
    1236:    48 8b 45 f8              mov    -0x8(%rbp),%rax    // rax = this.v1
    123a:    8b 50 04                 mov    0x4(%rax),%edx    // edx = rax+0x4 = this.v2
    123d:    48 8b 45 f8              mov    -0x8(%rbp),%rax    // rax = this.v1
    1241:    8b 00                    mov    (%rax),%eax        // eax = this.v1
    1243:    89 c6                    mov    %eax,%esi        // esi = this.v1
    1245:    48 8d 3d b8 0d 00 00     lea    0xdb8(%rip),%rdi        # 2004 <_IO_stdin_used+0x4> // rdi = "%d, %d\n"
    124c:    b8 00 00 00 00           mov    $0x0,%eax            // eax = 0
    1251:    e8 1a fe ff ff           callq  1070 <printf@plt>    // printf(rdi, esi, edx)
    1256:    90                       nop
    1257:    c9                       leaveq                    // ===> mov %rbp,%rsp, pop %rbp
    1258:    c3                       retq                    // ===> pop %rip
    1259:    0f 1f 80 00 00 00 00     nopl   0x0(%rax)

/*
 * arm
 */

int main()
{
   104b0:    b580          push    {r7, lr}
   104b2:    b084          sub    sp, #16                /* sp = sp - 16 */
   104b4:    af00          add    r7, sp, #0            /* 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                /* r0 = this */
   104d2:    f000 f82f     bl    10534 <_ZN1c4dumpEv>    /* c1调用dump */
    c2.dump();
   104d6:    463b          mov    r3, r7                /* r3 = sp */
   104d8:    4618          mov    r0, r3                /* r0 = r3 */
   104da:    f000 f82b     bl    10534 <_ZN1c4dumpEv>    /* c2调用dump */

    return 0;
   104de:    2300          movs    r3, #0            /* r3 = 0 */
}
   104e0:    4618          mov    r0, r3                /* r0 = 0 */
   104e2:    3710          adds    r7, #16            /* r7 += 16 */
   104e4:    46bd          mov    sp, r7                /* 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]    /* r3 = r7+4 = this */
   104f2:    f240 229b     movw    r2, #667    ; 0x29b
   104f6:    601a          str    r2, [r3, #0]    /* r3+0 = this.v1 = 667 */
        v2 = 999;
   104f8:    687b          ldr    r3, [r7, #4]    /* r3 = r7+4 = this */
   104fa:    f240 32e7     movw    r2, #999    ; 0x3e7
   104fe:    605a          str    r2, [r3, #4]    /* r3+4 = this.v2 = 999 */
    }
   10500:    687b          ldr    r3, [r7, #4]    /* r3 = r7+4 = this */
   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]    /* 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]    /* 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]    /* r3 = this */
   1053e:    6819          ldr    r1, [r3, #0]    /* r1 = [r3+0] = v1 */
   10540:    687b          ldr    r3, [r7, #4]    /* r3 = this */
   10542:    685b          ldr    r3, [r3, #4]    /* r3 = [r3+4] = v2 */
   10544:    461a          mov    r2, r3            /* r2 = r3 = 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 <printf@plt>    /* printf(r0, r1, r2) */
    }
   10552:    bf00          nop
   10554:    3708          adds    r7, #8
   10556:    46bd          mov    sp, r7
   10558:    bd80          pop    {r7, pc}

#endif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值