我是.Net的新手,我想首先了解基础知识。MSIL和Java字节码有什么区别?
我是.Net的新手,我想首先了解基础知识。MSIL和Java字节码有什么区别?
Answers:
首先,我要说的是,我不认为Java字节码与MSIL之间的细微差别不会使.NET开发新手感到困扰。它们都具有定义抽象目标机器的相同目的,该目标机器是最终使用的物理机器之上的一层。
MSIL和Java字节码非常相似,实际上有一个名为Grasshopper的工具可以将MSIL转换为Java字节码,我是Grasshopper开发团队的一员,所以我可以分享一些(淡淡的)知识。请注意,.NET Framework 2.0发布后,我停止了这一工作,因此其中某些事情可能不再适用(如果这样,请发表评论,我会予以纠正)。
struct)相对应的值语义。enums不仅仅是整数类型的包装器,而Javaenums则是完全成熟的类(感谢Internet Friend)的评论)。out和ref参数。还有其他语言差异,但大多数差异不是在字节码级别表达的,例如,如果内存服务于Java的非static内部类(.NET中不存在)不是字节码功能,则编译器将生成一个附加参数,以内部类的构造函数并传递外部对象。.NET lambda表达式也是如此。
CIL(MSIL的专有名称)和Java字节码彼此相同,不同之处更多。但是有一些重要的区别:
1)CIL从一开始就被设计为多种语言的目标。因此,它支持更丰富的类型系统,包括有符号和无符号类型,值类型,指针,属性,委托,事件,泛型,具有单个根的对象系统等。CIL支持初始CLR语言(C#和VB.NET)不需要的功能,例如全局功能和尾部调用优化。相比之下,Java字节码被设计为Java语言的目标,并且反映了Java本身中的许多约束。使用Java字节码编写C或Scheme会更加困难。
2)CIL旨在轻松集成到本机库和非托管代码中
3)Java字节码设计为可解释或编译,而CIL设计为仅假定JIT编译。也就是说,Mono的初始实现使用解释器而不是JIT。
4)CIL被设计(并指定)为具有人类可读可写的汇编语言形式,可以直接映射到字节码形式。我相信Java字节码(顾名思义)仅是机器可读的。当然,Java字节码相对容易地反编译回原始Java,如下所示,它也可以“反汇编”。
我应该注意,JVM(其中的大多数)比CLR(其中的任何一个)具有更高的优化程度。因此,原始性能可能是偏爱Java字节码的原因。不过,这是一个实现细节。
有人说Java字节码设计为多平台,而CIL仅设计为Windows。不是这种情况。.NET框架中有一些“ Windows”机制,但CIL中没有。
作为上述第4点的示例,我不久前将玩具Java编写为CIL编译器。如果您向该编译器提供以下Java程序:
class Factorial{
    public static void main(String[] a){
    System.out.println(new Fac().ComputeFac(10));
    }
}
class Fac {
    public int ComputeFac(int num){
    int num_aux ;
    if (num < 1)
        num_aux = 1 ;
    else 
        num_aux = num * (this.ComputeFac(num-1)) ;
    return num_aux ;
    }
}
我的编译器将吐出以下CIL:
.assembly extern mscorlib { }
.assembly 'Factorial' { .ver  0:0:0:0 }
.class private auto ansi beforefieldinit Factorial extends [mscorlib]System.Object
{
   .method public static default void main (string[] a) cil managed
   {
      .entrypoint
      .maxstack 16
      newobj instance void class Fac::'.ctor'()
      ldc.i4 3
      callvirt instance int32 class Fac::ComputeFac (int32)
      call void class [mscorlib]System.Console::WriteLine(int32)
      ret
   }
}
.class private Fac extends [mscorlib]System.Object
{
   .method public instance default void '.ctor' () cil managed
   {
      ldarg.0
      call instance void object::'.ctor'()
      ret
   }
   .method public int32 ComputeFac(int32 num) cil managed
   {
      .locals init ( int32 num_aux )
      ldarg num
      ldc.i4 1
      clt
      brfalse L1
      ldc.i4 1
      stloc num_aux
      br L2
   L1:
      ldarg num
      ldarg.0
      ldarg num
      ldc.i4 1
      sub
      callvirt instance int32 class Fac::ComputeFac (int32)
      mul
      stloc num_aux
   L2:
      ldloc num_aux
      ret
   }
}
这是一个有效的CIL程序,可以将其输入到CIL汇编程序中,例如 ilasm.exe以创建可执行文件。如您所见,CIL是一种完全人类可读和可写的语言。您可以在任何文本编辑器中轻松创建有效的CIL程序。
您也可以使用编译javac器编译上述Java程序,然后通过javap“反汇编程序”运行生成的类文件以获取以下信息:
class Factorial extends java.lang.Object{
Factorial();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return
public static void main(java.lang.String[]);
  Code:
   0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   new #3; //class Fac
   6:   dup
   7:   invokespecial   #4; //Method Fac."<init>":()V
   10:  bipush  10
   12:  invokevirtual   #5; //Method Fac.ComputeFac:(I)I
   15:  invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
   18:  return
}
class Fac extends java.lang.Object{
Fac();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return
public int ComputeFac(int);
  Code:
   0:   iload_1
   1:   iconst_1
   2:   if_icmpge   10
   5:   iconst_1
   6:   istore_2
   7:   goto    20
   10:  iload_1
   11:  aload_0
   12:  iload_1
   13:  iconst_1
   14:  isub
   15:  invokevirtual   #2; //Method ComputeFac:(I)I
   18:  imul
   19:  istore_2
   20:  iload_2
   21:  ireturn
}
该javap输出不编译(据我所知),但如果你把它比作CIL输出上面可以看到两个非常相似。
他们本质上是在做同样的事情,MSIL是Microsoft的Java字节码版本。
内部的主要区别是:
K John Gough在这篇文章中可以找到更多的信息和详细的比较(后记文档)
CIL(又称MSIL)旨在为人类可读。Java字节码不是。
可以将Java字节码看作是不存在的硬件(但可以模拟JVM)的机器代码。
CIL更像是汇编语言-距机器代码仅一步之遥,同时仍是人类可读的。
差别不大。两者都是您编写的代码的中间格式。在执行时,虚拟机将执行托管的中间语言,这意味着虚拟机将控制变量和调用。甚至还有我现在不记得的一种语言,它可以以相同的方式在.Net和Java上运行。
基本上,这只是同一件事的另一种格式
编辑:找到了语言(除了Scala):是FAN(http://www.fandev.org/),看起来很有趣,但是还没有时间评估
Serge Lidin撰写了一本有关MSIL详细信息的体面的书:Expert .NET 2.0 IL Assembler。通过使用.NET Reflector和Ildasm(教程)查看简单的方法,我还能够快速掌握MSIL。。
MSIL和Java字节码之间的概念非常相似。
我认为MSIL不应与Java字节码进行比较,而应与“组成Java字节码的指令”进行比较。
没有反汇编的Java字节码的名称。“ Java字节码”应该是非官方的别名,因为我在官方文档中找不到它的名称。 Java类文件反汇编器说
为类中的每个方法打印出反汇编的代码,即组成Java字节码的指令。这些都记录在Java虚拟机规范中。
“ Java VM指令”和“ MSIL”都被组装为.NET字节码和Java代码,它们是人类不可读的。