จากบทความที่ผ่านมาทำให้เรารู้จักกับ Managed mode ในแบบของ .Net Framework ซึ่งไม่ว่าจะใช้ภาษาอะไรในชุดของ .Net Framework ตัว compiler จะ compile code เพื่อที่จะได้ Managed code ที่ภายในบรรจุภาษา IL
ในบทความนี้ผมจะพาผู้อ่านมาลองเขียนภาษา IL แบบง่ายๆ กันดูครับ ตัวอย่างทั่วไปก็คงหนีไม่พ้น Hello World
เราดูตัวอย่าง code ข้างล่างกันเลยครับ
//Test.IL
.assembly extern mscorlib {}
.assembly Test
{
.ver 1:0:1:0
}
.method static void main() cil managed
{
.entrypoint
ldstr "Hello World from IL Assembly Language."
call void [mscorlib]System.Console::WriteLine (string)
ret
}
//Test.IL
.assembly extern mscorlib {}
.assembly Test
{
.ver 1:0:1:0
}
.method static void main() cil managed
{
.entrypoint
ldstr "Hello World from IL Assembly Language."
call void [mscorlib]System.Console::WriteLine (string)
ret
}
Code นี้สามารถเขียนด้วยโปรแกรม text editor ธรรมดาเช่นโปรแกรม Notepad จากนั้น save ลง file ชื่อ "HelloWorld.il"
เรามาดูคำอธิบายทีล่ะบรรทัดน่ะครับ
//Test.IL
เครื่องหมาย // เป็นตัวบอกให้ compiler รู้ว่านี้คือ comment ตัว compiler จะไม่ compile code ในส่วนนี้ วิธีใช้ comment ก็จะเหมือนกับภาษาของ .Net Framework ทั่วๆ ไปครับ เช่น คำสั่ง /* .... */ สำหรับ comment เป็น block
.assembly extern mscorlib {}
ภาษา IL จะมีจุด (.) หรือ period sign ไว้เป็นตัวนำหน้าคำสั่ง สำหรับคำสั่ง .assembly เป็นตัวบอกให้ compiler รู้ว่าเราจะมีการเรึยกใช้ library ภายนอก ในตัวอย่างคือ mscorlib.dll
.assembly Test
{
.ver 1:0:1:0
}
{
.ver 1:0:1:0
}
สำหรับคำสั่งนี้ จะเป็นการใส่รายละเอียดของ Managed module จากตัวอย่างเป็นการกำหนดให้ module มีชื่อว่า Test และระบุ version ของ module เป็น version 1.0.1.0 ด้วยคำสั่ง .ver 1:0:1:0
สำหรับคำสั่ง .ver สามารถเปรียบเทียบกับ code ของ C# คือ [assembly: AssemblyVersion("1.0.1.0")] คำสั่งนี้จะอยู่ใน File ที่ชื่อ AssemblyInfo.cs ใน folder Property ของ Project
.method static void main() cil managed
คำสั่งนี้จะบอกให้ compiler รู้ว่า ตั้งแต่ { จนถึง } คือ code ของ function ที่ชื่อ main()
cil managed ก็บอกให้รู้ว่า function main เป็นชนิด managed code
cil managed ก็บอกให้รู้ว่า function main เป็นชนิด managed code
สามาถเปรียบเทียบกับ code ของ C# ได้คือ static void Main()
.entrypoint บอกให้ compiler รู้ว่า method นี้เป็น entry point สำหรับ entry point ผมได้อธิบายไปแล้วที่ http://tuchay.blogspot.com/2015/07/unmanaged-code-vs-managed-code-2.html
คำสั่งนี้เก็บตัวอักษรลงใน stack memory โดยที่ไม่ได้เก็บลงตัวแปร
call void [mscorlib]System.Console::WriteLine (string)
บรรทัดนี้ก็จะเป็นการเรียกใช้ Console.WriteLine ของ namespace System ที่ป็น library อยู่ใน file mscorlib.dll
บรรทัดนี้ก็จะเป็นการเรียกใช้ Console.WriteLine ของ namespace System ที่ป็น library อยู่ใน file mscorlib.dll
parameter ที่ใส่ลงใน WriteLine ไม่ได้กำหนดเป็นตัวแปร นั้นหมายถึง compiler จะไปเอามาจาก stack memory โดยดึงมาจากส่วนบนสุดของ memory (เราเพิ่งใส่ string ไปใน stack memory ด้วย คำสั่ง ldstr)
เมื่อดึงมาแล้วก็จะทำการแสดงผลในหน้าจอว่า "Hello World from IL Assembly Language."
คำสั่ง ret เป็นตัวบอก compiler ว่า method นี้สิ้นสุดแค่นี้ ตรงนี้สำคัญน่ะครับถึงแม้ว่า method main จะมี return function เป็น void หมายถึงไม่มีอะไรที่ต้อง return ออกไป ภาษา IL ยังจำเป็นต้องมีคำสั่ง ret ครับถ้าไม่ใส่เราจะได้ error ต้อง runtime ครับ
หลังจากเขียน code แล้ว save ลง file test.il เราจะได้ IL code แล้ว แต่ file นี้ยังไม่สามารถ execute ได้ อย่าลืมน่ะครับ โคงสร้างของ managed code ต้องประกอบด้วย 4 ส่วนที่สำคัญรายละเอียดผมอธิบายไปแล้วที่ http://tuchay.blogspot.com/2015/07/unmanaged-code-vs-managed-code-2.html
เราสามารถสร้างอีก 3 ส่วนที่เหลือ ได้ด้วยคำสั่ง ilasm ดูตัวอย่างรูปข้างล่างครับ
จากนั้นเราก็จะได้ Managed file ที่มีครบทั้ง 4 ส่วนที่มีชื่อ file ว่า test.exe แล้วน่ะครับ เมื่อเรา execute test.exe ก็จะได้ผลลัพท์ดังรูปข้างล่างครับ
บทความต่อๆ ไปผมจะอธิบายเรื่อ CLR กับ IL โดยจะค่อยๆ เจาะลึกไปเรื่อยๆ น่ะครับ
พบกันใหม่บทความหน้าครับ
TuChay
ไม่มีความคิดเห็น:
แสดงความคิดเห็น