C ++汇编代码分析(用clang编译)

时间:2018-05-15 00:05:44

标签: c++ binary clang

我试图找出C ++二进制代码的样子,特别是对于虚函数调用。我想出了一些奇怪的事情。我有以下C ++代码:

#include <iostream>

using namespace std;

class Base {
 public:
  virtual void print() { cout << "from base" << endl; }
};

class Derived : public Base {
 public:
  virtual void print() { cout << "from derived" << endl; }
};

int main() {
  Base *b;
  Derived d;
  d.print();
  b = &d;
  b->print();
  return 0;
}

我用clang ++编译它,然后使用objdump:

00000000004008b0 <main>:
  4008b0:   55                      push   rbp
  4008b1:   48 89 e5                mov    rbp,rsp
  4008b4:   48 83 ec 20             sub    rsp,0x20
  4008b8:   48 8d 7d e8             lea    rdi,[rbp-0x18]
  4008bc:   c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
  4008c3:   e8 28 00 00 00          call   4008f0 <Derived::Derived()>
  4008c8:   48 8d 7d e8             lea    rdi,[rbp-0x18]
  4008cc:   e8 5f 00 00 00          call   400930 <Derived::print()>
  4008d1:   48 8d 7d e8             lea    rdi,[rbp-0x18]
  4008d5:   48 89 7d f0             mov    QWORD PTR [rbp-0x10],rdi
  4008d9:   48 8b 7d f0             mov    rdi,QWORD PTR [rbp-0x10]
  4008dd:   48 8b 07                mov    rax,QWORD PTR [rdi]
  4008e0:   ff 10                   call   QWORD PTR [rax]
  4008e2:   31 c0                   xor    eax,eax
  4008e4:   48 83 c4 20             add    rsp,0x20
  4008e8:   5d                      pop    rbp
  4008e9:   c3                      ret    
  4008ea:   66 0f 1f 44 00 00       nop    WORD PTR [rax+rax*1+0x0]

我的问题是为什么在汇编代码中,我们有以下代码:

  4008b8:   48 8d 7d e8             lea    rdi,[rbp-0x18]
  4008d1:   48 8d 7d e8             lea    rdi,[rbp-0x18]

1 个答案:

答案 0 :(得分:2)

d中的本地变量main()存储在[rbp-0x18]位置。这是在main()的堆栈上分配的自动存储中。

lea    rdi,[rbp-0x18]

此行将d的地址加载到rdi寄存器中。按照惯例,Derived的成员函数将rdi视为this指针。