我是.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代码,它们是人类不可读的。