กลับไปหน้าบทความ

อ่าน 7 นาที

ภาษากลางทั่วไป

ภาษาตัวกลางทั่วไป ( CIL ) ซึ่งเดิมเรียกว่า ภาษาตัวกลางของ Microsoft ( MSIL ) หรือ ภาษาตัวกลาง ( IL ) [ 1 ] คือชุดคำสั่งไบนารีของ ภาษาตัวกลาง ที่กำหนดไว้ในข้อกำหนด...

ภาษากลางทั่วไป

ภาษาตัวกลางทั่วไป ( CIL ) ซึ่งเดิมเรียกว่าภาษาตัวกลางของ Microsoft ( MSIL ) หรือภาษาตัวกลาง ( IL ) [ 1 ]คือชุดคำสั่งไบนารีของภาษาตัวกลาง ที่กำหนดไว้ในข้อกำหนด โครงสร้างพื้นฐานภาษาทั่วไป (CLI) [ 2 ]คำสั่ง CIL จะถูกดำเนินการโดยสภาพแวดล้อมรันไทม์ที่เข้ากันได้กับ CIL เช่นCommon Language Runtimeภาษาที่กำหนดเป้าหมาย CLI จะคอมไพล์เป็น CIL CIL เป็นไบต์โค้ดแบบอิงตามสแต็กและเชิงวัตถุ โดยทั่วไปแล้วรันไทม์ จะคอมไพ ล์ คำสั่ง CIL เป็นโค้ดเนทีฟแบบทันที

CIL เดิมทีรู้จักกันในชื่อ Microsoft Intermediate Language (MSIL) ในช่วงเบต้าของการเปิดตัวภาษา .NET เนื่องจากการกำหนดมาตรฐานของC#และ CLI ทำให้ไบต์โค้ดนี้เป็นที่รู้จักอย่างเป็นทางการในชื่อ CIL [ 3 ] คำจำกัดความไวรัส ของ Windows Defenderยังคงอ้างถึงไบนารีที่คอมไพล์ด้วย MSIL [ 4 ]

ข้อมูลทั่วไป

ระหว่างการคอมไพล์ภาษาการเขียนโปรแกรม CLIโค้ดต้นฉบับจะถูกแปลงเป็นโค้ด CIL แทนที่จะเป็นโค้ดออบเจ็กต์ เฉพาะแพลตฟอร์มหรือโปรเซสเซอร์ CIL เป็น ชุดคำสั่งที่ไม่ขึ้นกับ CPUและแพลตฟอร์ม ซึ่งสามารถดำเนินการได้ในสภาพแวดล้อมใดๆ ที่รองรับโครงสร้างพื้นฐานภาษาทั่วไป เช่นรันไทม์ .NETบนWindowsหรือ รันไทม์ Mono แบบข้ามแพลตฟอร์ม ในทางทฤษฎีแล้ว สิ่งนี้จะช่วยลดความจำเป็นในการแจกจ่ายไฟล์ปฏิบัติการที่แตกต่างกันสำหรับแพลตฟอร์มและประเภท CPU ที่แตกต่างกัน โค้ด CIL จะได้รับการตรวจสอบความปลอดภัยระหว่างรันไทม์ ซึ่งให้ความปลอดภัยและความน่าเชื่อถือที่ดีกว่าไฟล์ปฏิบัติการที่คอมไพล์แบบดั้งเดิม[ 5 ] [ 6 ]

ขั้นตอนการดำเนินการมีดังนี้:

  1. โค้ดต้นฉบับจะถูกแปลงเป็นไบต์โค้ด CIL และสร้างแอสเซมบลี CLI ขึ้นมา
  2. เมื่อเรียกใช้โค้ดแอสเซมบลี CIL โค้ดนั้นจะถูกส่งผ่าน คอมไพเลอร์ JITของรันไทม์เพื่อสร้างโค้ดเนทีฟ อาจใช้การคอมไพล์ล่วงหน้าได้เช่นกัน ซึ่งจะช่วยลดขั้นตอนนี้ แต่จะทำให้ไฟล์ปฏิบัติการไม่สามารถพกพาได้ในหลายแพลตฟอร์ม
  3. หน่วยประมวลผลของคอมพิวเตอร์จะประมวลผลโค้ดเนทีฟ

คำแนะนำ

ไบต์โค้ด CIL มีคำสั่งสำหรับงานกลุ่มต่างๆ ดังต่อไปนี้:

แบบจำลองการคำนวณ

ภาษา Common Intermediate Language (CLI) เป็นภาษาเชิงวัตถุและใช้สแต็กซึ่งหมายความว่าพารามิเตอร์คำสั่งและผลลัพธ์จะถูกเก็บไว้ในสแต็กเดียว แทนที่จะเก็บไว้ในรีจิสเตอร์หลายตัวหรือตำแหน่งหน่วยความจำอื่นๆ เหมือนในภาษาโปรแกรม ส่วน ใหญ่

โค้ดที่บวกเลขสองจำนวนในภาษาแอสเซมบลี x86โดยที่ eax และ edx ระบุรีจิสเตอร์อเนกประสงค์ สองตัวที่แตกต่างกัน :

เพิ่มeax , edx

เขียนโค้ดในภาษาตัวกลาง (IL) โดยที่ 0 คือ eax และ 1 คือ edx:

ldloc.0 // ผลักตัวแปรโลคอล 0 ลงในสแต็กldloc.1 // ผลักตัวแปรโลคอล 1 ลงในสแต็กadd // ดึงค่าสองค่าบนสุด ของ สแต็ ก ออกมาแล้วบวกเข้าด้วยกัน จากนั้นผลักผลลัพธ์ ลงในสแต็กstloc.0 // ดึงค่าค่าบนสุดของสแต็กออกมาแล้วเก็บค่าไว้ในตัวแปรโลคอล 0

ในตัวอย่างหลังนี้ ค่าของรีจิสเตอร์สองตัว คือ eax และ edx จะถูกผลักลงบนสแต็กก่อน เมื่อมีการเรียกใช้คำสั่งบวก ตัวถูกดำเนินการจะถูก "ดึงออก" หรือดึงกลับมา และผลลัพธ์จะถูก "ผลัก" หรือจัดเก็บลงบนสแต็ก จากนั้นค่าที่ได้จะถูกดึงออกจากสแต็กและจัดเก็บไว้ใน eax

แนวคิดเชิงวัตถุ

CIL ถูกออกแบบมาให้เป็นภาษาเชิงวัตถุ ผู้ใช้สามารถสร้างวัตถุ เรียกใช้เมธอด และใช้งานสมาชิกประเภทอื่นๆ เช่น ฟิลด์ได้

ทุกเมธอด (ยกเว้นบางกรณี) จำเป็นต้องอยู่ในคลาส ดังนั้นเมธอดแบบ static นี้ก็เช่นกัน:

.class public Foo { .method public static int32 Add ( int32 , int32 ) cil managed { .maxstack 2 ldarg .0 // โหลดอาร์กิวเมนต์แรก; ldarg .1 // โหลดอาร์กิวเมนต์ที่สอง; add // บวกกัน; ret // คืนค่าผลลัพธ์; } }

เมธอด Add ไม่จำเป็นต้องประกาศอินสแตนซ์ของ Foo เพราะมันถูกประกาศเป็นแบบ static อยู่แล้ว และสามารถใช้งานได้ดังนี้ใน C#:

int r = Foo.Add ( 2 , 3 ) ; // 5

ในระบบ CIL จะมีลักษณะดังนี้:

ldc.i4.2 ldc.i4.3 call int32 Foo :: Add ( int32 , int32 ) stloc.0

คลาสอินสแตนซ์

คลาสอินสแตนซ์ประกอบด้วยคอนสตรัคเตอร์ อย่างน้อยหนึ่งตัว และ สมาชิก อินสแตนซ์ บางส่วน คลาสต่อไปนี้มีชุดเมธอดที่แสดงถึงการกระทำของวัตถุรถยนต์

. class public Car { . method public specialname rtspecialname instance void . ctor ( int32 , int32 ) cil managed { /* Constructor */ }. เมธอดpublic void Move ( int32 ) cil managed { /* ละเว้นการใช้งาน */ } . เมธอดpublic void TurnRight () cil managed { /* ละเว้นการใช้งาน */ } . เมธอดpublic void TurnLeft () cil managed { /* ละเว้นการใช้งาน */ } . เมธอดpublic void Brake () cil managed { /* ละเว้นการใช้งาน */ } }

การสร้างวัตถุ

ในภาษา C# การสร้างอินสแตนซ์ของคลาสทำได้ดังนี้:

รถmyCar = รถใหม่( 1 , 4 ); รถyourCar = รถใหม่( 1 , 3 );

และข้อความเหล่านั้นก็โดยคร่าวๆ เหมือนกับคำแนะนำเหล่านี้ใน CIL:

ldc . i4 .1ldc . i4 .4อินสแตนซ์newobj void Car ::. ctor ( int32 , int32 )stloc .0 // myCar = รถใหม่ (1, 4);ldc . i4 .1ldc . i4 .3อินสแตนซ์newobj void Car ::. ctor ( int32 , int32 )stloc .1 // yourCar = new Car(1, 3);

การเรียกใช้เมธอดอินสแตนซ์

ในภาษา C# การเรียกใช้เมธอดแบบอินสแตนซ์จะทำได้ดังนี้:

myCar . ย้าย( 3 );

ตามที่อ้างถึงใน CIL:

ldloc .0 // โหลดอ็อบเจ็กต์ "myCar" ลงบนสแต็กldc . i4 .3 เรียกอินสแตนซ์void Car :: Move ( int32 )

เมตาเดตา

โครงสร้างพื้นฐานภาษาทั่วไป (CLI) บันทึกข้อมูลเกี่ยวกับคลาสที่คอมไพล์แล้วในรูปแบบของเมตาเดตาเช่นเดียวกับไลบรารีประเภทในโมเดลออบเจ็กต์คอมโพเนนต์สิ่งนี้ช่วยให้แอปพลิเคชันสามารถรองรับและค้นหาอินเทอร์เฟซ คลาส ประเภท เมธอด และฟิลด์ในแอสเซมบลีได้ กระบวนการอ่านเมตาเดตาดังกล่าวเรียกว่า " การสะท้อน " (reflection)

เมตาเดตาคือข้อมูลในรูปแบบของ "แอตทริบิวต์" แอตทริบิวต์สามารถปรับแต่งได้โดยการขยายAttributeคลาส นี่เป็นคุณสมบัติที่ทรงพลัง ช่วยให้ผู้สร้างคลาสสามารถเพิ่มข้อมูลเพิ่มเติมให้กับคลาส ซึ่งผู้ใช้งานคลาสสามารถนำไปใช้ได้อย่างมีความหมายหลากหลายวิธี ขึ้นอยู่กับขอบเขตการใช้งาน

ตัวอย่าง

ด้านล่างนี้คือโปรแกรม "Hello, World!" พื้นฐาน ที่เขียนด้วยภาษาแอสเซมบลี CIL โปรแกรมนี้จะแสดงข้อความ "Hello, world!"

. assembly Hello {} . assembly extern mscorlib {} . method static void Main () { . entrypoint . maxstack 1 ldstr "Hello, world!" call void [ mscorlib ] System . Console :: WriteLine ( string ) ret }

โค้ดต่อไปนี้มีความซับซ้อนมากขึ้นในแง่ของจำนวนโอเปอเรชันโค้ด

โค้ดนี้สามารถนำไปเปรียบเทียบกับโค้ดที่เกี่ยวข้องในบทความเกี่ยวกับไบต์โค้ดของภาษาจาวาได้ เช่นกัน

static void Main ( string [ ] args ) { for ( int i = 2 ; i < 1000 ; i ++ ) { for ( int j = 2 ; j < i ; j ++ ) { if ( i % j == 0 ) goto outer ; } Console.WriteLine ( i ) ; outer :; } }

ในไวยากรณ์แอสเซมเบลอร์ CIL จะมีลักษณะดังนี้:

. เมธอดprivate hidebysig static void Main ( string [] args ) cil managed { . entrypoint . maxstack 2 . locals init ( int32 V_0 , int32 V_1 )แอลดีซีi4 .2 stloc .0 br . s IL_001f IL_0004 : ldci4 .2 stloc .1 br . s IL_0011 IL_0008 : ldloc .0 ldloc .1 rem brfalses IL_001b ldloc .1 ldci4 .1 เพิ่มstloc .1 IL_0011 : ldloc .1 ldloc .0 blts IL_0008 ldloc .0 การเรียกระบบเป็นโมฆะ[ mscorlib ] คอนโซล:: WriteLine ( int32 ) IL_001b : ldloc .0 ldci4 .1 เพิ่มstloc .0 IL_001f : ldloc .0 ldci4 0x3e8 blt . s IL_0004 ยกเลิก}

นี่เป็นเพียงภาพจำลองลักษณะของ CIL ใน ระดับ เครื่องเสมือน (VM) เมื่อคอมไพล์แล้ว เมธอดจะถูกเก็บไว้ในตาราง และคำสั่งจะถูกเก็บไว้เป็นไบต์ภายในแอสเซมบลี ซึ่งเป็นไฟล์ปฏิบัติการแบบพกพา (PE)

รุ่น

โค้ดแอสเซมบลีและคำสั่ง CIL ถูกสร้างขึ้นโดยคอมไพเลอร์หรือยูทิลิตี้ที่เรียกว่าIL Assembler ( ILAssembly ) ซึ่งมาพร้อมกับสภาพแวดล้อมการทำงาน

นอกจากนี้ โค้ด CIL ที่ประกอบเสร็จแล้วยังสามารถแยกกลับเป็นโค้ดได้อีกครั้งโดยใช้IL Disassembler (ILDASM) ยังมีเครื่องมืออื่นๆ เช่น.NET Reflectorที่สามารถถอดรหัส CIL เป็นภาษาโปรแกรมระดับสูง (เช่น C# หรือVisual Basic ) ได้อีกด้วย ทำให้ CIL เป็นเป้าหมายที่ง่ายมากสำหรับการวิศวกรรมย้อนกลับ คุณสมบัตินี้พบได้ในไบต์โค้ดของ Javaเช่นกัน อย่างไรก็ตาม มีเครื่องมือที่สามารถทำให้โค้ดอ่านยาก แต่ยังคงสามารถทำงาน ได้

การประหารชีวิต

การรวบรวมแบบทันเวลาพอดี

การคอมไพล์แบบทันเวลา ( Just-in-Time Compilationหรือ JIT) คือการแปลงไบต์โค้ดให้เป็นโค้ดที่ซีพียูสามารถเรียกใช้งานได้ทันที การแปลงจะเกิดขึ้นทีละน้อยในระหว่างการทำงานของโปรแกรม การคอมไพล์แบบ JIT ให้การปรับแต่งที่เหมาะสมกับสภาพแวดล้อมและการตรวจสอบความถูกต้องของแอสเซมบลี เพื่อให้บรรลุเป้าหมายนี้ คอมไพเลอร์ JIT จะตรวจสอบเมตาเดตาของแอสเซมบลีเพื่อหาการเข้าถึงที่ไม่ถูกต้องและจัดการกับการละเมิดอย่างเหมาะสม

การรวบรวมล่วงหน้า

สภาพแวดล้อมการทำงานที่เข้ากันได้ กับ CLIยังมีตัวเลือกในการทำการคอมไพล์ล่วงหน้า ( Ahead-of-time compilationหรือ AOT) ของแอสเซมบลีเพื่อให้ทำงานได้เร็วขึ้นโดยการกำจัดกระบวนการ JIT ในระหว่างการรันไทม์

ใน.NET Frameworkมีเครื่องมือพิเศษที่เรียกว่าNative Image Generator (NGEN) ซึ่งทำหน้าที่ AOT (Automatic Object-Oriented) อีกแนวทางหนึ่งสำหรับ AOT คือCoreRTซึ่งช่วยให้สามารถคอมไพล์โค้ด .NET Core ไปเป็นไฟล์ปฏิบัติการเดียวโดยไม่ต้องพึ่งพา Runtime นอกจาก นี้ Monoยังรองรับการคอมไพล์แบบ AOT ด้วย

คำสั่งเกี่ยวกับตัวชี้ - C++/CLI

ความแตกต่างที่เห็นได้ชัดจากไบต์โค้ดของ Java คือ CIL มาพร้อมกับ คำสั่ง ldind`init`, stind` ldlocainit` และคำสั่งเรียก (call) จำนวนมาก ซึ่งเพียงพอสำหรับการจัดการตัวชี้ข้อมูล/ฟังก์ชันที่จำเป็นในการคอมไพล์โค้ด C/C++ ให้เป็น CIL

คลาสA { public : virtual void __stdcall meth () {} }; void test_pointer_operations ( int param ) { int k = 0 ; int * ptr = & k ; * ptr = 1 ; ptr = & param ; * ptr = 2 ; A a ; A * ptra = &a } a ; ptra -> meth (); }

โค้ดที่เกี่ยวข้องใน CIL สามารถแสดงได้ดังนี้:

. เมธอดassembly static void modopt ([ mscorlib ] System . Runtime . CompilerServices . CallConvCdecl ) test_pointer_operations ( int32 param ) cil managed { . vtentry 1 : 1 // ขนาดโค้ด 44 (0x2c) . maxstack 2 . locals ([ 0 ] int32 * ptr , [ 1 ] valuetype A * V_1 , [ 2 ] valuetype A * a , [ 3 ] int32 k ) // k = 0; IL_0000 : ldc . i4 .0 IL_0001 : stloc .3 // ptr = &k; IL_0002 : ldloca . s k // คำสั่งโหลดที่อยู่ของ local IL_0004 : stloc .0 // *ptr = 1; IL_0005 : ldloc .0 IL_0006 : ldci4 .1 IL_0007 : stindi4 // คำสั่งทางอ้อม// ptr = ¶m IL_0008 : ldarga s param // คำแนะนำที่อยู่ของพารามิเตอร์โหลดIL_000a : stloc .0 // *ptr = 2 IL_000b : ldloc .0 IL_000c : ldc i4 .2 IL_000d : สติi4 // a = A ใหม่; IL_000e : ldlocas a IL_0010 : เรียกvaluetype A * modopt ([ mscorlib ] System . Runtime . CompilerServices . CallConvThiscall ) ' A .{ ctor } ' ( valuetype A * modopt ([ mscorlib ]ระบบ. รันไทม์บริการคอมไพเลอร์IsConst ) modopt ([ mscorlib ] ระบบ. Runtime . CompilerServices . IsConst )) IL_0015 : pop // ptra = &a; IL_0016 : ldlocas a IL_0018 : stloc .1 // ptra->meth(); IL_0019 : ldloc .1 IL_001a : ซ้ำIL_001b : ldindi4 // อ่าน VMT สำหรับการโทรเสมือนIL_001c : ldind i4 IL_001d : calli unmanaged stdcall void modopt ([ mscorlib ] System . Runtime . CompilerServices . CallConvStdcall )( native int ) IL_0022 : ret } // end of method 'Global Functions'::test_pointer_operations

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • บ็อค, เจสัน (2002). การเขียนโปรแกรม CIL: เบื้องหลัง .NET . สำนักพิมพ์ A. ISBN 978-1590590416.
  • โครงสร้างพื้นฐานภาษาทั่วไป (มาตรฐาน ECMA-335)
  • “มาตรฐาน ECMA C# และ Common Language Infrastructure” บนเว็บไซต์ Visual Studio
  • โปรแกรม "สวัสดีโลก" ใน CIL
  • ความเร็ว: NGen เร่งประสิทธิภาพของคุณด้วยคุณสมบัติใหม่ที่ทรงพลัง -- นิตยสาร MSDN เมษายน 2548
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Common_Intermediate_Language&oldid=1351660961 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ภาษากลางทั่วไป

ภาษาตัวกลางทั่วไป ( CIL ) ซึ่งเดิมเรียกว่า ภาษาตัวกลางของ Microsoft ( MSIL ) หรือ ภาษาตัวกลาง ( IL ) [ 1 ] คือชุดคำสั่งไบนารีของ ภาษาตัวกลาง ที่กำหนดไว้ในข้อกำหนด...

ข้อมูลทั่วไป

ระหว่างการคอม ไพล์ภาษาการเขียนโปรแกรม CLI โค้ด ต้นฉบับ จะถูกแปลงเป็นโค้ด CIL แทนที่จะเป็น โค้ดออบเจ็กต์ เฉพาะแพลตฟอร์มหรือโปรเซสเซอร์ CIL เป็น ชุดคำสั่งที่ไม่ขึ้นกับ CPU และแพลตฟอร์ม ซึ่งสามารถดำเนินการได้ในสภาพแวดล้อมใดๆ ที่รองรับโครงสร้างพื้นฐานภาษาทั่วไป...

คำแนะนำ

ไบต์โค้ด CIL มี คำสั่ง สำหรับงานกลุ่มต่างๆ ดังต่อไปนี้:

แบบจำลองการคำนวณ

ภาษา Common Intermediate Language (CLI) เป็นภาษาเชิงวัตถุและ ใช้สแต็ก ซึ่งหมายความว่าพารามิเตอร์คำสั่งและผลลัพธ์จะถูกเก็บไว้ในสแต็กเดียว แทนที่จะเก็บไว้ในรีจิสเตอร์หลายตัวหรือตำแหน่งหน่วยความจำอื่นๆ เหมือนใน ภาษาโปรแกรม ส่วน ใหญ่