Tôi mới sử dụng .Net và tôi đang cố gắng hiểu những điều cơ bản trước. Sự khác biệt giữa MSIL và Java bytecode là gì?
Tôi mới sử dụng .Net và tôi đang cố gắng hiểu những điều cơ bản trước. Sự khác biệt giữa MSIL và Java bytecode là gì?
Câu trả lời:
Trước hết, hãy để tôi nói rằng tôi không nghĩ rằng sự khác biệt nhỏ giữa Java bytecode và MSIL là điều gì đó khiến một nhà phát triển .NET mới làm quen với nó phải bận tâm. Cả hai đều phục vụ cùng một mục đích là xác định một máy đích trừu tượng là một lớp phía trên máy vật lý đang được sử dụng cuối cùng.
MSIL và Java bytecode rất giống nhau, trên thực tế có một công cụ tên là Grasshopper dịch MSIL sang Java bytecode, tôi là thành viên của nhóm phát triển Grasshopper nên tôi có thể chia sẻ một chút kiến thức (còn mờ nhạt) của mình. Xin lưu ý rằng tôi đã ngừng làm việc này vào khoảng thời gian .NET framework 2.0 ra mắt nên một số điều này có thể không còn đúng nữa (nếu có, vui lòng để lại nhận xét và tôi sẽ sửa lại).
struct
).enums
không hơn nhiều so với các lớp bao bọc xung quanh các kiểu số nguyên trong khi Javaenums
là các lớp chính thức khá nhiều (cảm ơn Internet Friend đã nhận xét).out
và ref
các tham số.Có những khác biệt về ngôn ngữ khác nhưng hầu hết chúng không được thể hiện ở cấp mã byte, ví dụ: nếu bộ nhớ phục vụ các static
lớp không phải bên trong của Java (không tồn tại trong .NET) không phải là một tính năng bytecode, thì trình biên dịch sẽ tạo một đối số bổ sung để phương thức khởi tạo của lớp bên trong và chuyển đối tượng bên ngoài. Điều này cũng đúng với biểu thức .NET lambda.
CIL (tên riêng của MSIL) và mã bytecode của Java giống nhau hơn là chúng khác nhau. Tuy nhiên, có một số khác biệt quan trọng:
1) CIL được thiết kế ngay từ đầu để phục vụ như một mục tiêu cho nhiều ngôn ngữ. Do đó, nó hỗ trợ một hệ thống kiểu phong phú hơn nhiều bao gồm các kiểu có dấu và không dấu, kiểu giá trị, con trỏ, thuộc tính, đại biểu, sự kiện, tổng thể, hệ thống đối tượng có một gốc duy nhất, v.v. CIL hỗ trợ các tính năng không cần thiết cho các ngôn ngữ CLR ban đầu (C # và VB.NET) chẳng hạn như các chức năng toàn cục và tối ưu hóa cuộc gọi đuôi . Để so sánh, Java bytecode được thiết kế như một mục tiêu cho ngôn ngữ Java và phản ánh nhiều ràng buộc được tìm thấy trong chính Java. Sẽ khó hơn rất nhiều để viết C hoặc Scheme bằng Java bytecode.
2) CIL được thiết kế để tích hợp dễ dàng vào các thư viện gốc và mã không được quản lý
3) Mã bytecode của Java được thiết kế để có thể thông dịch hoặc biên dịch trong khi CIL được thiết kế với giả định chỉ biên dịch JIT. Điều đó nói rằng, việc triển khai Mono ban đầu sử dụng một trình thông dịch thay vì một JIT.
4) CIL được thiết kế ( và được chỉ định ) để có một dạng ngôn ngữ hợp ngữ có thể đọc và ghi được của con người, ánh xạ trực tiếp tới dạng bytecode. Tôi tin rằng mã bytecode của Java (như tên của nó) có nghĩa là chỉ máy có thể đọc được. Tất nhiên, Java bytecode tương đối dễ dàng được dịch ngược trở lại Java gốc và như hình dưới đây, nó cũng có thể được "tháo rời".
Tôi nên lưu ý rằng JVM (hầu hết trong số chúng) được tối ưu hóa cao hơn CLR (bất kỳ trong số chúng). Vì vậy, hiệu suất thô có thể là một lý do để thích nhắm mục tiêu theo mã byte Java. Đây là một chi tiết thực hiện mặc dù.
Một số người nói rằng mã bytecode của Java được thiết kế để đa nền tảng trong khi CIL được thiết kế chỉ dành cho Windows. Đây không phải là trường hợp. Có một số isms "Windows" trong .NET framework nhưng không có trong CIL.
Như ví dụ của điểm số 4) ở trên, tôi đã viết một trình biên dịch Java sang CIL đồ chơi một thời gian trước. Nếu bạn cung cấp trình biên dịch này chương trình Java sau:
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 ;
}
}
trình biên dịch của tôi sẽ tạo ra CIL sau:
.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
}
}
Đây là một chương trình CIL hợp lệ có thể được đưa vào một trình hợp dịch CIL như ilasm.exe
để tạo một tệp thực thi. Như bạn có thể thấy, CIL là một ngôn ngữ hoàn toàn có thể đọc và ghi được của con người. Bạn có thể dễ dàng tạo các chương trình CIL hợp lệ trong bất kỳ trình soạn thảo văn bản nào.
Bạn cũng có thể biên dịch chương trình Java ở trên bằng javac
trình biên dịch và sau đó chạy các tệp lớp kết quả thông qua javap
"trình tháo gỡ" để có được những điều sau:
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
}
Đầu javap
ra không thể biên dịch được (theo hiểu biết của tôi) nhưng nếu bạn so sánh nó với đầu ra CIL ở trên, bạn có thể thấy rằng cả hai rất giống nhau.
Về cơ bản họ đang làm điều tương tự, MSIL là phiên bản Java bytecode của Microsoft.
Sự khác biệt chính trong nội bộ là:
Có thể tìm thấy nhiều thông tin hơn và so sánh chi tiết trong bài viết này của K John Gough (tài liệu tái bút)
CIL hay còn gọi là MSIL được thiết kế để con người có thể đọc được. Java bytecode thì không.
Hãy nghĩ về Java bytecode là mã máy cho phần cứng không tồn tại (nhưng JVM mô phỏng).
CIL giống ngôn ngữ hợp ngữ hơn - một bước so với mã máy, trong khi con người vẫn có thể đọc được.
Không có nhiều sự khác biệt. Cả hai đều là định dạng trung gian của mã bạn đã viết. Khi được thực thi, Máy ảo sẽ thực thi ngôn ngữ trung gian được quản lý có nghĩa là Máy ảo điều khiển các biến và lệnh gọi. Thậm chí có một ngôn ngữ mà tôi không nhớ ngay bây giờ có thể chạy trên .Net và Java theo cùng một cách.
Về cơ bản, nó chỉ là một định dạng khác cho cùng một thứ
Chỉnh sửa: Đã tìm thấy ngôn ngữ (ngoài Scala): Đó là FAN ( http://www.fandev.org/ ), trông rất thú vị, nhưng chưa có thời gian để đánh giá
Đồng ý, sự khác biệt là đủ phút để ăn nhập khi mới bắt đầu. Nếu bạn muốn học .Net bắt đầu từ những điều cơ bản, tôi khuyên bạn nên xem Cơ sở hạ tầng ngôn ngữ chung và Hệ thống kiểu chung.
Serge Lidin là tác giả của một cuốn sách chi tiết về MSIL: Expert .NET 2.0 IL Assembler . Tôi cũng có thể chọn MSIL nhanh chóng bằng cách xem các phương pháp đơn giản sử dụng .NET Reflector và Ildasm (Hướng dẫn) .
Các khái niệm giữa MSIL và Java bytecode rất giống nhau.
Tôi nghĩ MSIL không nên so sánh với mã bytecode của Java mà là "hướng dẫn bao gồm các mã bytecodes của Java".
Không có tên của bytecode java đã được tháo rời. "Java Bytecode" phải là một bí danh không chính thức, vì tôi không thể tìm thấy tên của nó trong tài liệu chính thức. Trình gỡ mã tệp lớp Java nói
In ra mã được tháo rời, tức là, các hướng dẫn bao gồm các mã bytecodes của Java, cho mỗi phương thức trong lớp. Những điều này được ghi lại trong Đặc tả máy ảo Java.
Cả "Hướng dẫn Java VM" và "MSIL" đều được tập hợp thành mã bytecode .NET và mã Java, mà con người không thể đọc được.