C++ 汇编代码查看

gcc 编译为汇编代码

原始C++代码如下:

#include "stdio.h"

class Animal {
public:
    virtual void name() { printf("I'm Animal\n"); }
};

class Cat : public Animal {
public:
    virtual void name() override { printf("I'm Cat\n"); }
};

void func(Animal *animal) {
    animal->name();
}

int main(void) {
    func(new Animal());
    func(new Cat());
    return 0;
}

编译成汇编代码:

g++ -S test.cpp -o test.s

查看:

cat test.s

部分结果:

main:
.LFB3:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    pushq   %rbx
    subq    $8, %rsp
    .cfi_offset 3, -24

你发现你完全看不懂

使用 as 展示汇编代码

另一种更好的做法是使用as
编译成汇编代码:

g++ -S -fverbose-asm -g test.cpp -o test.s

查看:

as -alhnd test.s

现在是把代码和汇编代码对应起来了:

  16:test.cpp      **** 
  17:test.cpp      **** int main(void) {
 202                    .loc 1 17 16
.........
 212                # test.cpp:18:     func(new Animal());
  18:test.cpp      ****     func(new Animal());
 213                    .loc 1 18 21
 214 002b BF080000      movl    $8, %edi    #,
 214      00
 215 0030 E8000000      call    _Znwm   #
 215      00
 216 0035 4889C3        movq    %rax, %rbx  # tmp86, _3
 217 0038 48C70300      movq    $0, (%rbx)  #, MEM[(struct Animal *)_4]._vptr.Animal
 217      000000
 218 003f 4889DF        movq    %rbx, %rdi  # _3,
 219 0042 E8000000      call    _ZN6AnimalC1Ev  #
 219      00
 220                # test.cpp:18:     func(new Animal());

这种情况看汇编代码比刚才更清楚一些。

使用 objdump 进行反汇编

如果直接编成机器码,需要使用objdump进行反汇编:

g++ -save-temps -fverbose-asm -g -o test test.cpp
objdump -S --disassemble test

效果如下:

0000000000400654 <main>:

int main(void) {
  400654:   55                      push   %rbp
  400655:   48 89 e5                mov    %rsp,%rbp
  400658:   53                      push   %rbx
  400659:   48 83 ec 08             sub    $0x8,%rsp
    func(new Animal());
  40065d:   bf 08 00 00 00          mov    $0x8,%edi
  400662:   e8 d9 fe ff ff          callq  400540 <_Znwm@plt>
  400667:   48 89 c3                mov    %rax,%rbx
  40066a:   48 c7 03 00 00 00 00    movq   $0x0,(%rbx)
  400671:   48 89 df                mov    %rbx,%rdi
  400674:   e8 6d 00 00 00          callq  4006e6 <_ZN6AnimalC1Ev>
  400679:   48 89 df                mov    %rbx,%rdi
  40067c:   e8 b1 ff ff ff          callq  400632 <_Z4funcP6Animal>

感觉使用objdump效果最好,但还有效果更好的。

使用 godbolt 可视化结果

这个网站: https://godbolt.org
真的非常好用,效果如下:

在这里插入图片描述
非常炫酷,而且一一对应。

参考:

发布了502 篇原创文章 · 获赞 145 · 访问量 48万+

猜你喜欢

转载自blog.csdn.net/zhangpeterx/article/details/100120219