代码之家  ›  专栏  ›  技术社区  ›  user142019

汇编程序如何处理类和对象,它们如何存储在RAM和可执行文件中?

  •  2
  • user142019  · 技术社区  · 14 年前

    汇编程序在编译程序时如何处理类和对象?这是如何存储在RAM和可执行文件中的?

    首先,根据类的大小分配内存,例如20字节。在这20个字节中,类的所有变量都被存储。但有两个问题:

    1. 指向类的指针如何工作?
    2. 被调用的方法如何知道 对象 它属于?

    你能给我解释一下吗?(如果使用示例代码,我更喜欢Objto-C、C++和x86程序集)

    2 回复  |  直到 14 年前
        1
  •  4
  •   Necrolis    14 年前

    汇编程序不知道类是什么,它只汇编机器代码,偶尔宏也会抛出这些代码。就所有意图和目的而言,类完全是一个带有可选vftable的结构,所有处理和类“特殊特性”(虚拟化、多态性、inheiritanc等)都是在创建IR代码的中间阶段完成的。内存的分配将与结构、变量、数组或任何其他数据“blob”(静态或动态地,考虑对齐、常量和打包)相同,但用于处理基于堆栈和静态的dtor展开(在IR级别再次执行)的支持代码除外,和静态初始化(尽管静态初始化可能发生在多个类对象上)。我建议你把这本龙书通读一遍(前八章将涵盖它),以便更清楚地了解编译器和汇编程序是如何工作的,因为这些事情不是由汇编程序处理的,而是由编译器的前端和/或后端处理的,这取决于编译器的IL是如何构造的。

        2
  •  3
  •   dennycrane    14 年前

    (2)成员函数由编译器重写。考虑 class A 如下所示。

    class A {
        int i;
    public:
        A () : i (0) { }
    
        void f (int a, char *b) { i = a; }
    }
    

    那么编译器是怎么做的 A::f 看起来像这样(伪代码):

    void A::f (A * const this, int a, char *b) { this->i = a; }
    

    现在考虑打电话给 甲:丙 .

    A a;
    a.f (25, "");
    

    编译器生成与此类似的代码(伪代码):

    A a;
    A::f (&a, 25, "");
    

    换句话说,编译器在 this 指向每个非静态成员函数和每个调用的指针都接收对其调用的实例的引用。这尤其意味着您可以在 NULL 指针。

    A *a = NULL;
    a->f (25, "");
    

    只有在实际引用非静态类成员变量时才会发生崩溃。 生成的崩溃报告还说明了问题(1)的答案。在很多情况下,你不会因为地址而崩溃 0 ,但有一个偏移量。该偏移量对应于被访问变量在编译器选择的内存布局中的偏移量 甲级 (在这种情况下,许多编译器实际上会用 0x0 甲级 记忆中的意志与 struct A { int i; }; ). 基本上,指向类的指针是指向等价C结构的指针。成员函数被实现为以实例引用作为第一个参数的自由函数。所有与公共、受保护和私有成员相关的访问检查都是由编译器预先完成的,生成的程序集对这些概念一无所知。事实上,早期版本的C++被认为是一组聪明的C宏。

    当您使用虚拟函数时,内存布局(通常)会发生一些变化。

    推荐文章