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
真的非常好用,效果如下:

在這裏插入圖片描述
非常炫酷,而且一一對應。

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章