我是.Net的新手,我想先了解一些基础知识。MSIL和Java字节码有什么区别?
发布于 2012-02-06 11:15:53
CIL (MSIL的专有名称)和Java字节码的相同之处多于不同之处。不过,也有一些重要的区别:
1) CIL从一开始就被设计为多种语言的目标。因此,它支持更丰富的类型系统,包括有符号和无符号类型、值类型、指针、属性、委托、事件、泛型、具有单个根的对象系统等等。CIL支持初始CLR语言(C#和VB.NET)不需要的功能,如全局函数和tail-call optimizations。相比之下,Java字节码被设计为Java语言的目标,并反映了Java本身中的许多约束。使用Java字节码编写C或Scheme会困难得多。
2) CIL旨在轻松集成到本机库和非托管代码中
3) Java字节码被设计为可以解释或编译,而CIL仅假设JIT编译。也就是说,Mono的初始实现使用的是解释器而不是JIT。
4) CIL被设计为(and specified)具有人类可读和可写的汇编语言形式,该形式直接映射到字节码形式。我相信Java字节码(顾名思义)只是机器可读的。当然,Java字节码相对容易地反编译回原始的Java,如下所示,它也可以被“反汇编”。
我应该指出的是,JVM (大多数)比CLR (它们中的任何一个)都要进行高度优化。因此,原始性能可能是首选以Java字节码为目标的原因。不过,这只是一个实现细节。
有人说,Java字节码被设计成多平台的,而CIL被设计成只适用于Windows。事实并非如此。在.NET框架中有一些“窗口”isms,但在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程序,可以输入到像ilasm.exe
这样的CIL汇编程序中以创建可执行文件。如您所见,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输出进行比较,就会发现两者非常相似。
发布于 2008-09-18 18:17:52
没有那么大的区别。两者都是您编写的代码的中间格式。在执行时,虚拟机将执行中间语言托管,这意味着虚拟机控制变量和调用。甚至有一种我现在不记得的语言,可以在.Net和Java上以同样的方式运行。
基本上,它只是同一事物的另一种格式
编辑:找到了语言(除了Scala):它是FAN (http://www.fandev.org/),看起来很有趣,但还没有时间来评估
发布于 2008-09-18 18:18:01
CIL,也称为MSIL,旨在为人类提供可读性。Java字节码则不是。
可以将Java字节码看作是不存在的硬件的机器码(但JVM会模拟它)。
CIL更像是汇编语言--离机器代码只有一步之遥,同时仍然是人类可读的。
https://stackoverflow.com/questions/95163
复制相似问题