- ภาษาแอสเซมบลีจัดระเบียบคำสั่งตามวัตถุประสงค์ เช่น การถ่ายโอน การคำนวณ การควบคุมการไหล และอื่นๆ
- คำสั่งแต่ละคำสั่งประกอบด้วยโอปโค้ดและตัวดำเนินการซึ่งมีรูปแบบต่างกันขึ้นอยู่กับสถาปัตยกรรม
- มีโหมดการกำหนดที่อยู่หลายโหมดสำหรับการเข้าถึงข้อมูล เช่น ทันที โดยตรง และโดยอ้อม
ภาษาแอสเซมบลีเป็นหนึ่งในเสาหลักพื้นฐานของการพัฒนาซอฟต์แวร์นับตั้งแต่เริ่มมีการประมวลผล แม้ว่าภาษาขั้นสูงจะมีบทบาทสำคัญในปัจจุบัน แต่ภาษาแอสเซมเบลอร์ยังคงใช้กันอย่างแพร่หลายและมีความเกี่ยวข้องในสภาพแวดล้อมที่การควบคุมฮาร์ดแวร์ การเพิ่มประสิทธิภาพ หรือข้อจำกัดทรัพยากรเป็นสิ่งสำคัญ
ในบทความนี้ เราจะเจาะลึกถึงประเภทของคำสั่งภาษาแอสเซมบลี วิเคราะห์โครงสร้าง วัตถุประสงค์ โหมดการกำหนดแอดเดรส และวิธีการจัดระเบียบคำสั่งเหล่านี้ในสถาปัตยกรรมต่างๆ นอกจากนี้คุณยังจะได้พบกับตัวอย่าง รูปแบบ และภาพรวมที่ครอบคลุม ซึ่งจะช่วยให้คุณเข้าใจตรรกะเบื้องหลังคำสั่งเหล่านี้อย่างถ่องแท้ ซึ่งทำงานร่วมกับฮาร์ดแวร์อย่างใกล้ชิด
คำสั่งในภาษาแอสเซมบลีคืออะไร?
คำสั่งแอสเซมบลีคือคำสั่งที่ซีพียูสามารถเข้าใจได้โดยตรง (เมื่อถูกแปลงเป็นรหัสเครื่องโดยโปรแกรมแอสเซมเบลอร์แล้ว) แต่ละคำสั่งมีวัตถุประสงค์เฉพาะ และโดยปกติจะประกอบด้วยตัวย่อที่แสดงถึงการดำเนินการ และตัวถูกดำเนินการ หนึ่งตัวหรือมากกว่านั้น ซึ่งระบุว่าข้อมูลถูกดึงมาจากที่ใด และ/หรือผลลัพธ์ถูกจัดเก็บไว้ที่ใด
คำสั่งเหล่านี้ขึ้นอยู่กับสถาปัตยกรรมโปรเซสเซอร์เป็นอย่างมาก ดังนั้น CPU แต่ละประเภท (ไม่ว่าจะเป็น x86, ARM, MIPS เป็นต้น) จึงประกอบด้วยชุดคำสั่งของตัวเองซึ่งมีรูปแบบและความสามารถเฉพาะตัว
โครงสร้างของคำสั่ง
คำแนะนำโดยทั่วไปจะประกอบด้วยสองส่วน:
- รหัสการดำเนินการ (โอปโค้ด) : ระบุการดำเนินการที่จะดำเนินการ เช่นการเพิ่มเติม การเคลื่อนย้ายข้อมูล การเปรียบเทียบ ฯลฯ
ตัวถูกดำเนินการ (Operands) คือข้อมูลที่จำเป็นต่อการดำเนินการ และสามารถเก็บไว้ในรีจิสเตอร์ หน่วยความจำ หรือเป็นค่าคงที่ได้ไม่ใช่ทุกคำสั่งที่จะต้องมีตัวถูกดำเนินการ และในบางกรณี ตัวถูกดำเนินการอาจอยู่ในคำสั่งโดยปริยาย หรือเก็บไว้ในรีจิสเตอร์ที่กำหนดไว้ล่วงหน้า
ประเภทของคำสั่งในภาษาแอสเซมบลี
คำสั่งภาษาแอสเซมบลีสามารถแบ่งออกเป็นกลุ่มต่างๆ ได้หลายกลุ่ม ขึ้นอยู่กับฟังก์ชันการทำงานที่ดำเนินการในโปรแกรม ที่เกี่ยวข้องที่สุดมีรายละเอียดด้านล่างนี้:
1. คำแนะนำการโอนข้อมูล
คำสั่งเหล่านี้อนุญาตให้คัดลอกข้อมูลจากที่หนึ่งไปยังอีกที่หนึ่งโดยไม่เปลี่ยนแปลงเนื้อหาของข้อมูลต้นทาง คำสั่งเหล่านี้มีความสำคัญอย่างยิ่งสำหรับการย้ายข้อมูลระหว่างรีจิสเตอร์ หน่วยความจำ และอุปกรณ์ต่อพ่วง
คำแนะนำบางส่วนที่พบบ่อยที่สุดในกลุ่มนี้ได้แก่:
- เอ็มวี: คัดลอกเนื้อหาของตัวดำเนินการหนึ่งไปยังอีกตัวดำเนินการหนึ่ง ตัวอย่างเช่น,
MOV AX, BXคัดลอกเนื้อหาของ BX ไปยัง AX - MOVS / MOVSB / MOVSW: ย้ายสตริงจากที่อยู่ต้นทาง (SI) ไปยังที่อยู่ปลายทาง (DI) ทำให้กระบวนการถ่ายโอนเป็นอัตโนมัติ
- ลอดส์ / ลอดส์บี / ลอดส์ดับบลิว: โหลดค่าจากที่อยู่ที่ระบุโดยรีจิสเตอร์ SI ลงในตัวสะสม (AL หรือ AX)
- อ่าน: โหลดที่อยู่ที่มีผลบังคับใช้แทนค่า มีประโยชน์สำหรับการรับที่อยู่ของตัวแปรหรือโครงสร้าง
2. คำแนะนำการใช้แบตเตอรี่
สแต็กเป็นโครงสร้างแบบ LIFO (เข้าหลังออกก่อน)ซึ่งใช้สำหรับจัดเก็บข้อมูลชั่วคราว ส่งผ่านพารามิเตอร์ หรือบันทึกบริบทการทำงาน
- ดัน: เก็บค่าบนสแต็ก โดยลดค่าตัวชี้ SP
- POP: ดึงค่าล่าสุดที่จัดเก็บอยู่ในสแต็ก โดยเพิ่ม SP
- พุชฟ / ป็อปฟ : พวกเขาจะจัดเก็บและดึงสถานะของแฟล็ก CPU บนสแต็ก
3. คำสั่งทางคณิตศาสตร์และตรรกะ
คำสั่ง เหล่านี้อนุญาตให้ทำการคำนวณและดำเนินการกับบิตได้คำสั่งเหล่านี้มีความสำคัญอย่างยิ่งต่อการจัดการข้อมูลตัวเลขและการตัดสินใจในกระบวนการทำงานของโปรแกรม
ในบรรดาที่ใช้มากที่สุดเราพบ:
- เพิ่ม / สมัครสมาชิก: การบวกและการลบ
- มูล / อิมูล : การคูณไบนารี
- DIV / IDIV: การหาร (จำนวนเต็มหรือมีเครื่องหมาย)
- และ / หรือ / XOR / ไม่: การดำเนินการทางลอจิกแบบบิต
- SHL / SHR / ROL / ROR: การเลื่อนบิตและการหมุน
4. คำแนะนำการควบคุมการไหล
คำสั่งเหล่านี้ช่วยให้คุณสามารถแก้ไขลำดับการทำงานของโปรแกรมได้เช่น การเพิ่มการกระโดด หรือการเรียกใช้คำสั่งอื่นแบบมีเงื่อนไขและไม่มีเงื่อนไข
- เจเอ็มพี: กระโดดไปยังที่อยู่อื่นในโปรแกรมโดยไม่มีเงื่อนไข
- โทร / RET: เรียกไปที่ซับรูทีนแล้วกลับมา
- เจอี/เจเอ็นอี/เจจี/เจแอล/เจแซด/เจเอ็นแซด: การกระโดดแบบมีเงื่อนไข ซึ่งจะดำเนินการหากมีการตรงตามเงื่อนไขบางประการ (หลังการเปรียบเทียบ)
5. คำสั่งอินพุต/เอาต์พุต (I/O)
คำสั่ง เหล่านี้ช่วยให้สามารถสื่อสารระหว่างโปรเซสเซอร์และอุปกรณ์ภายนอกได้ โดยคำสั่งเหล่านี้อนุญาตให้สามารถอ่านและเขียนข้อมูลเข้า/ออกจากพอร์ต (ฮาร์ดแวร์) ได้
- น่า: อ่านข้อมูลจากพอร์ตอินพุต
- ออก: ส่งข้อมูลไปยังพอร์ตเอาต์พุต
6. คำสั่งจุดลอยตัว
ซีพียูหลายตัวมีตัวประมวลผลร่วมทางคณิตศาสตร์ (หรือคำสั่งพิเศษ)ที่ออกแบบมาเพื่อทำงานกับตัวเลขทศนิยม (จุดลอยตัว) คำสั่งเหล่านี้ช่วยให้สามารถดำเนินการต่างๆ ได้ เช่น:
- การบวก การลบ การคูณ และการหารจำนวนจริง
- การดำเนินการตรีโกณมิติ (ไซน์, โคไซน์, แทนเจนต์)
- การดำเนินการลอการิทึม เลขชี้กำลัง และรากที่สอง
คำแนะนำเหล่านี้โดยทั่วไปเป็นไปตามมาตรฐาน IEEE 754สำหรับความแม่นยำเชิงตัวเลข
โหมดการระบุที่อยู่
ส่วนสำคัญอย่างยิ่งของการออกแบบคำสั่งคือวิธีการระบุตำแหน่งของตัวถูกดำเนินการโหมดการกำหนด แอดเดรส จะกำหนดวิธีการที่ซีพียูเข้าถึงข้อมูล
1. การระบุที่อยู่ทันที
ข้อมูลถูกรวมอยู่ในคำสั่งโดยตรงวิธีนี้รวดเร็ว แต่ไม่สามารถแก้ไขค่าต่างๆ ได้โดยไม่ต้องเปลี่ยนคำสั่ง
MOV AX, 5
2. การกล่าวถึงโดยตรง
ที่อยู่หน่วยความจำที่ประกอบด้วยข้อมูลจะถูกระบุไว้อย่างชัดเจน
MOV AX,
3. การระบุที่อยู่ทางอ้อม
ที่อยู่ที่มีประสิทธิภาพจะได้รับจากเนื้อหาของระเบียนมีความยืดหยุ่นสูงและใช้สำหรับโครงสร้างและรายการเชื่อมโยง
MOV AX,
4. การระบุที่อยู่แบบดัชนี
การคำนวณที่อยู่ทำได้โดยการบวกฐานและดัชนี (ตัวอย่างเช่น เพื่อวนลูปผ่านอาร์เรย์)โดยใช้รีจิสเตอร์พิเศษ เช่น SI, DI หรือรีจิสเตอร์ฐาน + ออฟเซ็ต
MOV AX,
รูปแบบคำสั่ง: ประเภทต่างๆ ขึ้นอยู่กับสถาปัตยกรรม
โครงสร้างของคำสั่งอาจแตกต่างกันไปขึ้นอยู่กับสถาปัตยกรรม รูปแบบทั่วไปได้แก่:
รูปแบบ 4 ทิศทาง
ประกอบด้วยตัวถูกดำเนินการสองตัว ตำแหน่งที่เก็บผลลัพธ์ และที่อยู่ของคำสั่งถัดไปปัจจุบันถือว่าล้าสมัยแล้วเนื่องจากมีความซับซ้อนเกินไป
รูปแบบ 3 ทิศทาง
รูปแบบนี้ระบุตัวถูกดำเนินการสองตัวและที่อยู่ปลายทาง เป็นรูปแบบที่พบได้ทั่วไปในสถาปัตยกรรม RISC สมัยใหม่
รูปแบบ 2 ทิศทาง
ใช้ตัวถูกดำเนินการต้นทางและตัวถูกดำเนินการปลายทาง (ปลายทางสามารถกำหนดค่าได้ด้วย) วิธีนี้เป็นที่นิยมใช้ในสถาปัตยกรรม x86 และ CISC อื่นๆ
รูปแบบทางเดียว
มีการระบุตัวถูกดำเนินการเพียงตัวเดียว อีกตัวหนึ่งจะถือว่าเป็นตัวสะสม วิธีนี้พบได้ทั่วไปในโปรเซสเซอร์รุ่นเก่าและระบบที่ไม่ซับซ้อน
รูปแบบที่อยู่ 0 (ตามสแต็ก)
การดำเนินการเหล่านี้ใช้สแต็กในการดึงและจัดเก็บตัวดำเนินการและผลลัพธ์ซึ่งมีประสิทธิภาพมากสำหรับเครื่องจักรที่ใช้สแต็ก เช่น เครื่องคิดเลขแบบตั้งโปรแกรมได้บางรุ่น
คำสั่งแมโครและรหัสคำสั่งเทียม
เพื่อเพิ่มประสิทธิภาพการทำงาน โปรแกรมแอสเซมเบลอร์หลายตัวจึงมีคำสั่งมาโครซึ่งจะขยายบรรทัดเดียวให้กลายเป็นคำสั่งจริงหลายคำสั่ง คำสั่งเหล่านี้มีประโยชน์สำหรับการหลีกเลี่ยงการทำซ้ำรูปแบบที่ซับซ้อน หรือสำหรับการสร้างโครงสร้างระดับสูง เช่น ลูปหรือคำสั่งเงื่อนไข
ลอส รหัสโอปโค้ดเทียม เป็นคำสั่งที่โปรแกรมแอสเซมเบลอร์แปลภายในให้เป็นลำดับคำสั่งจริง ตัวอย่างเช่น, NOP (ไม่มีการดำเนินการ) สามารถแปลว่า XCHG AX, AX บน CPU x86
คำสั่งแอสเซมเบลอร์
คำสั่งควบคุม ( หรือเรียกว่า การดำเนินการเสมือน ) ไม่ใช่คำสั่งในความหมายที่แท้จริง แต่ใช้เพื่อควบคุมกระบวนการประกอบโค้ด กำหนดข้อมูล ส่วนของโค้ด มาโคร เงื่อนไขการคอมไพล์ ฯลฯ
ตัวอย่างทั่วไปได้แก่:
- .ข้อมูล / .รหัส: บ่งบอกถึงส่วนข้อมูลหรือรหัส
- .org: กำหนดที่อยู่ที่จะเริ่มต้นการประกอบ
- .เท่ากับ: กำหนดค่าคงที่เชิงสัญลักษณ์
กรณีการใช้งานภาษาแอสเซมบลี
แม้ว่าจะมีภาษาโปรแกรมระดับสูงเกิดขึ้นมากมาย แต่ภาษาแอสเซมบลียังคงมีความสำคัญในหลายด้าน:
- การพัฒนาของระบบฝังตัวและไมโครคอนโทรลเลอร์
- การเขียนโปรแกรมไดร์เวอร์ บูตโหลดเดอร์ และ BIOS
- การเพิ่มประสิทธิภาพอย่างสูงสุดในแอพพลิเคชัน เช่น วิดีโอเกม หรือการเข้ารหัส
- การวิศวกรรมย้อนกลับ การดีบัก และการแฮ็กระดับต่ำ
นอกจากนี้ การฝึกอบรมภาษาแอสเซมบลียังคงมีความสำคัญอย่างยิ่งในหลักสูตรวิทยาการคอมพิวเตอร์และอิเล็กทรอนิกส์ เนื่องจากช่วยให้เข้าใจอย่างลึกซึ้งถึงวิธีการทำงานของโปรเซสเซอร์ วิธีการจัดเก็บและประมวลผลข้อมูล และวิธีการดำเนินการคำสั่งในระดับไบนารี
การทำความเข้าใจคำสั่งแอสเซมบลีทุกประเภท โครงสร้าง ฟังก์ชันการทำงาน และโหมดการระบุตำแหน่งจะสร้างรากฐานที่มั่นคงให้กับโปรแกรมเมอร์ที่ต้องการเจาะลึกการเขียนโปรแกรมระดับต่ำ หรือต้องการทำความเข้าใจว่าภาษาขั้นสูงถูกแปลเป็นโค้ดเครื่องอย่างไรในที่สุด แม้ว่าการใช้จะมีความเฉพาะเจาะจงมากขึ้น แต่ยังคงเป็นเครื่องมือสำคัญในหลายๆ ด้านที่สำคัญของการพัฒนาซอฟต์แวร์และระบบ