Assembly MIPS汇编中的面向对象继承

Assembly MIPS汇编中的面向对象继承,assembly,compilation,mips,code-generation,Assembly,Compilation,Mips,Code Generation,我是一名计算机科学专业的学生,目前正在修一门编译课程,在这门课程中,我们有一个项目,用Java语言的子集IC构建一个编译器。在最后一部分中,我需要从IR树生成无寄存器分配的MIPS程序集。 我试图理解对象实例是如何在MIPS程序集中表示的。我知道我需要为每个对象实例生成一个虚拟函数表(其中包含与该实例相关的函数地址)。 我的问题是: 我是否需要为类字段创建类似的表,因为字段也是继承的。你建议怎么做? 此外,如果有人能举例说明继承类和字段的对象实例的真实MIPS汇编代码的样子,我将不胜感激。 例如

我是一名计算机科学专业的学生,目前正在修一门编译课程,在这门课程中,我们有一个项目,用Java语言的子集IC构建一个编译器。在最后一部分中,我需要从IR树生成无寄存器分配的MIPS程序集。
我试图理解对象实例是如何在MIPS程序集中表示的。我知道我需要为每个对象实例生成一个虚拟函数表(其中包含与该实例相关的函数地址)。
我的问题是:
我是否需要为类字段创建类似的表,因为字段也是继承的。你建议怎么做?
此外,如果有人能举例说明继承类和字段的对象实例的真实MIPS汇编代码的样子,我将不胜感激。
例如,MIPS代码是什么样子的:

class A{
    int x;
    void f(){}
}

class B extends A{
    int y;
    void g(){}

    void main(){
      A newObj = new B();
      newObj.f();
      newObj.x++;
    }
}

我只回答问题的这一部分:

此外,如果有人能举例说明真正的MIPS汇编代码的外观,我将不胜感激

我确实把你的例子改写成C++,一个只有很少开关的C++编译器不会完全地优化它,并保持字段和调用。(如果您想知道为什么使用代码> Value,以及其他一些东西,只是为了防止编译器产生像返回值=5的组件,返回< /code >……C++编译器往往会有一些恼人的优化,当您只想看到一些“示例”代码时)。
A类{
公众:
挥发性int x;
虚空f(){
++x;
}
};
B类:公共A{
公众:
挥发性内质网;
B(国际一){
y=i;
x=i-1;
}
虚空f(){
x+=2;
}
void g(){
f();
x+=3;
++y;
}
};
整数英尺(整数英寸){
B*obj=新的B(英寸);
A*obj_A_别名=obj;
obj_A_alias->f();//调用B::f(),因为f是虚拟的
obj->g();
obj->f();
obj->A::f();//强制A::f()调用(在B实例上)
int结果=obj->x+obj->y;
删除obj;
返回结果;
}
现在,如果您将其放入并将编译器设置为MIPS gcc 5.4,使用选项
-O3-std=c++11-fno循环优化-fno内联
,您将获得以下输出:

$LFB0=。
A::f():
$LVL0=。
lw$2,4($4)
加上$2,$2,1
sw$2,4($4)
j$31
不
$LFB7=。
B::f():
$LVL1=。
lw$2,4($4)
加上$2,$2,2
sw$2,4($4)
j$31
不
$LFB3=。
A::A():
$LVL2=。
$LBB2=。
lui$2,%hi(A+8的vtable)
加上$2,$2,%lo(A+8的vtable)
j$31
sw$2,0($4)
$LBE2=。
A::A()=A::A()
$LFB5=。
B::B(int):
$LVL3=。
加上$sp,$sp,-40
sw$17,32($sp)
移动$17,$5
sw$31,36($sp)
sw$16,28($sp)
$LBB3=。
日本航空公司A::A()
移动$16,$4
$LVL4=。
加上$2,$17,-1
$LBE3=。
lw$31,36($sp)
$LBB4=。
sw$17,8($16)
sw$2,4($16)
lui$2,%hi(B+8的vtable)
$LBE4=。
lw$17,32($sp)
$LVL5=。
$LBB5=。
加上$2,$2,%lo(B+8的vtable)
sw$2,0($16)
$LBE5=。
lw$16,28($sp)
$LVL6=。
j$31
加上$sp,$sp,40
B::B(int)=B::B(int)
$LFB8=。
B::g():
$LVL7=。
lw$2,0($4)
加总$sp,$sp,-32
sw$16,24($sp)
sw$31,28($sp)
卢布$25,0($2)
日尔曼25美元
移动$16,$4
$LVL8=。
lw$2,4($16)
lw$31,28($sp)
加上$2,2,3
sw$2,4($16)
lw$2,8($16)
加上$2,$2,1
sw$2,8($16)
lw$16,24($sp)
$LVL9=。
j$31
加上$sp,$sp,32
$LFB9=。
英尺(整数):
$LVL10=。
lui$28%,hi(\u gnu\u本地\u gp)
加总$sp,$sp,-32
加上$28、$28、%lo(\u gnu\u本地\u gp)
sw$16,24($sp)
移动$16,$4
$LVL11=。
sw$31,28($sp)
lw$25,%call16(新操作员(未签名整数))(28美元)
1:25日尔曼
李$4,12#0xc
$LVL12=。
移动5美元,16美元
移动$16,$2
$LVL13=。
日本航空公司班机:班机(国际)
移动$4,$2
$LVL14=。
$LVL15=。
日本航空公司B::f()
移动$4,$16
$LVL16=。
日本航空公司B::g()
移动$4,$16
$LVL17=。
lw$2,0($16)
卢布$25,0($2)
日尔曼25美元
移动$4,$16
$LVL18=。
日本航空公司A::f()
移动$4,$16
$LVL19=。
移动$4,$16
lw$28,16($sp)
lw$2,4($16)
lw$16,8($16)
$LVL20=。
lw$25,%call16(操作员删除(无效*)($28)
$LVL21=。
1:25日尔曼
加16美元,2美元,16美元
$LVL22=。
移动$2,$16
lw$31,28($sp)
lw$16,24($sp)
$LVL23=。
j$31
加上$sp,$sp,32
A的typeinfo名称:
.ascii“1A\000”
A的类型信息:
.word vtable for uuuu cxxabiv1::uuu class_type_info+8
.word typeinfo用于
B的类型信息名称:
.ascii“1B\000”
B的类型信息:
.word vtable for uuu cxxabiv1::uu si_class_type_info+8
.word类型B的信息名称
.word typeinfo,用于
vtable for A:
.word 0
.word typeinfo,用于
.单词A::f()
B的vtable:
.word 0
.B的word typeinfo
.单词B::f()
在实际的站点上,您还将得到彩色提示,提示代码的哪一部分属于源代码的哪一部分(如果目标平台是MIPS64编译器的话,也有MIPS64编译器)


编辑:您可能还应该尝试
-O0
opti