动态调度如何在汇编中发生?

atk*_*yla 0 c++ x86 assembly

我在某个地方找到了一些代码并决定在汇编中吐出来试图找到差异.

#include <iostream>

class A {
    public:
        void f() const { std::cout << "A::f()" << std::endl; }
};

class B {
    public:
        void f() const { std::cout << "B::f()" << std::endl; }
};

int main()
{
    A a ;
    B b ;

    a.f() ;
    b.f() ;
}
Run Code Online (Sandbox Code Playgroud)

-

#include <iostream>

class base {
    public:
        virtual void f() const = 0 ;
        virtual ~base() {}
};

class A : public base {
    public:
        virtual void f() const { std::cout << "A::f()" << std::endl; }
};

class B : public base {
    public:
        virtual void f() const { std::cout << "B::f()" << std::endl; }
};

void dispatch(const base & x) {
    x.f();
}

int main() {
    A a ;
    B b ;

    dispatch(a) ;
    dispatch(b) ;
}
Run Code Online (Sandbox Code Playgroud)

我正在看这个类似的问题(如何判断一个程序是否通过查看程序集来使用动态调度)并试图在程序集中找到它,但是我不清楚.

这是两个程序的差异文件(http://www.diffchecker.com/b9y0v3ps).有人可以指出动态调度发生的位置,或许可以解释一下发生了什么以及两者之间的区别是什么?

Mik*_*our 5

从您链接到的程序集,非虚拟分派如下:

53    call _ZNK1A1fEv
Run Code Online (Sandbox Code Playgroud)

直接调用该函数.

虚拟调度如下:

53    mov  EAX, DWORD PTR [EBP - 4]
54    mov  ECX, DWORD PTR [EAX]
56    call DWORD PTR [ECX]
Run Code Online (Sandbox Code Playgroud)

从对象加载vtable的地址,然后从vtable加载函数地址,然后间接调用该函数.