4

私はこの非常に単純な C++ プログラムを作成しましたが、コンパイラが vtable を 2 つのポインター逆参照にまたがって配置する理由が気になりました。C++ プログラムは次のとおりです。

class Foo {
 public:
  virtual void bar() {
  }
};

int main(int argc, char *arv[]) {
  Foo foo;
  Foo *foo_p(&foo);
  foo_p->bar();
}

ここで、コンパイラによって生成されたアセンブリを確認できます。

$ g++ -ggdb -Wall -O0 -S test.cpp

関連するセクションは次のとおりです。

    .loc 1 9 0 
    leaq    -16(%rbp), %rax  # put the address of 'foo' in %rax
    movq    %rax, %rdi       # use it as the first argument of the following function
    call    _ZN3FooC1Ev      # call the Foo constructor
    .loc 1 10 0
    leaq    -16(%rbp), %rax  # put the address of 'foo' in %rax
    movq    %rax, -24(%rbp)  # create 'foo_p' on the stack
    .loc 1 11 0
    movq    -24(%rbp), %rax  # load 'foo_p' into %rax
    movq    (%rax), %rax     # dereference the pointer, put it in %rax
                             # %rax now holds the hidden pointer in 'foo', which is the vtable pointer
    movq    (%rax), %rdx     # dereference the pointer ::again:: (with an offset of 0), put it in %rdx
                             # %rdx now holds a function pointer from the vtable
    movq    -24(%rbp), %rax  # create the 'this' pointer (== foo_p) and put it in %rax
    movq    %rax, %rdi       # use the 'this' pointer as the first argument to the following function
    call    *%rdx            # call Foo::bar (via the vtable)

2 番目のポインター逆参照が必要なのはなぜですか? オブジェクトの「隠された」vtable ポインタが vtable を直接指していないのはなぜですか?

編集: ::is:: vtable を直接指しています。私はポインタと混同しました:-P

4

2 に答える 2

2

1 つ目はvtableポインタを%raxに置き、2 つ目は関数ポインタを に置きます%rdx

于 2013-04-17T08:11:49.393 に答える