มีความแตกต่างที่แท้จริงระหว่างคอมไพเลอร์และแอสเซมเบลอร์ไหม?


15

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


1
ประกอบเป็นคอมไพเลอร์ที่มีประสิทธิภาพเฉพาะชุดของงาน คำศัพท์มีความแตกต่างกันบ้างในทางปฏิบัติ แต่คำจำกัดความพื้นฐานของ "คอมไพเลอร์" (แปลระหว่างภาษา) ใช้
กราฟิลส์

ผู้ประกอบทั้งหมดเป็นคอมไพเลอร์ (ง่าย) เนื่องจากพวกเขาเปลี่ยนภาษาหนึ่งเป็นภาษาอื่น คอมไพเลอร์บางคนไม่ใช่แอสเซมเบลอร์
user253751

คำตอบ:


16

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


2
ทำไมการแปลจึงสามารถทำได้เพียงทางเดียว? นั่นหมายความว่าไม่สามารถสร้างรหัส asm ต้นทางสำหรับรหัสเครื่องที่กำหนด (และสถาปัตยกรรมเป้าหมาย) ได้หรือไม่ นั่นฟังดูง่ายสำหรับฉัน เพราะหากคำสั่งรหัสเครื่องที่ระบุสามารถจับคู่กับคำสั่ง asm หลายเครื่องเครื่องจะตัดสินใจว่าจะดำเนินการคำสั่งใดอย่างไร ฉันพลาดอะไรไปรึเปล่า?
Utku

3
AT(A)A

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

ฉันโพสต์ไว้ที่นี่cs.stackexchange.com/questions/98854/…
ทิม

ภาษาระดับกลางมักจะหมายถึงภาษาซึ่งเป็นเครื่องที่เป็นอิสระ
Yuval Filmus

11

บรรทัดล่างคือการเขียนคอมไพเลอร์สนุกกว่าแอสเซมเบลอร์ ภาษาแอสเซมบลีมักจะได้รับการออกแบบให้เกือบจะเป็นเรื่องเล็ก ๆ น้อย ๆ ที่จะแยกวิเคราะห์และตรวจสอบและมีแนวโน้มที่จะเกี่ยวข้องกับเครื่องปั่นไฟ - โต๊ะ ("opcode สำหรับเพิ่มคือ 01110", "สำหรับคำแนะนำในการโหลด ") โดยปกติแล้วส่วนที่น่าสนใจที่สุดของแอสเซมเบลอร์คือส่วนที่แก้ไขป้ายสัญลักษณ์เป็นตัวเลข

อย่างไรก็ตามแอสเซมบลีส่วนใหญ่สามารถทำเลขคณิตจำนวนเล็กน้อย (ตัวอย่างเช่นการรวมเลเบลสัญลักษณ์พร้อมค่าคงที่ขนาดเล็กเข้าด้วยกัน) และแอสเซมเบลอร์ส่วนใหญ่มีหรือรวมเข้ากับระบบประมวลผลแมโคร (ในระบบ Unix ส่วนใหญ่คุณสมบัติของมาโครจะได้รับจากการรัน C pre-processor บนชุดประกอบก่อนส่งผ่านไปยังแอสเซมเบลอร์ที่เหมาะสม)

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

ความแตกต่างนั้นเบลอมากขึ้นจากงานของนอร์แมนแรมซีย์โดยเฉพาะอย่างยิ่งภาษาแอสเซมบลีแบบพกพาC -ของเขา (บทความที่เกี่ยวข้องคือRamsey และ Peyton Jones "ภาษากลางระดับกลางเดียวที่รองรับการใช้งานหลายอย่างของข้อยกเว้น", Prog. Lang. Impl. และ Dsgn. , (PLDI-21): 285–298, 2000 ) และในที่สุดก็มี เป็นภาษาแอสเซมบลีที่พิมพ์จาก David Walker และ Greg Morrisett ด้วยแอสเซมเบลอร์ที่สามารถรับประกันความปลอดภัยของหน่วยความจำได้


0

คำตอบที่เรียบง่ายเล็กน้อยที่นี่ความเป็นจริงมีความซับซ้อนมากขึ้น ฉันคาดหวังความแตกต่างระหว่างแอสเซมเบลอร์ (A) และคอมไพเลอร์ (C) เป็นสิ่งอื่น:

  1. ซอร์สโค้ดหนึ่งบรรทัดเกี่ยวข้องโดยตรงกับ CPU opcode (A) หรือไม่ (C)
  2. ขึ้นอยู่กับ CPU จริง (A) หรือเครื่องจักรอิสระ (C)

เรามักจะเรียกภาษาแอสเซมบลี "ระดับต่ำ" และภาษาต้นฉบับที่คอมไพเลอร์เข้าใจ "ระดับสูง" (นี่คือการทำให้เข้าใจง่าย แต่ก็ยัง)

ในภาษาแอสเซมบลีคุณสามารถดำเนินการเพิ่มได้โดยพูดว่า:

  • เพิ่ม a, b (สำหรับ CPU หนึ่งตัว)
  • เพิ่ม R5, R6 (สำหรับ CPU อื่น)
  • เพิ่ม (A5), D2 (สำหรับ CPU อื่น)

ในภาษาระดับสูงคุณอาจเขียน:

  • x = y + z;

และสิ่งนี้อาจส่งผลให้มีคำสั่งหนึ่งคำสั่งหรือหลายร้อยคำสั่งขึ้นอยู่กับสถานการณ์หลายอย่างหนึ่งคือสิ่งที่ CPU ที่คอมไพเลอร์สร้างคำแนะนำสำหรับ

ดังที่คุณเห็นภาษาแอสเซมบลีบ่อยที่สุด: (A) ซอร์สโค้ดหนึ่งบรรทัดจะให้ซีพียู opcodes หนึ่งบรรทัดและมันขึ้นอยู่กับ CPU ที่คุณกำหนดเป้าหมายเป็นอย่างมาก คอมไพเลอร์ภาษาระดับสูง (C) จัดการรายละเอียดทั้งหมดเหล่านี้ให้คุณ - ซอร์สโค้ดหนึ่งบรรทัดอาจกลายเป็นศูนย์, หนึ่งหรือหลายซีพียู opcodes และคอมไพเลอร์จัดการรายละเอียดของสิ่งที่ CPU สามารถทำได้

คอมไพเลอร์ทุกวันนี้มักประกอบด้วยหลายขั้นตอน พวกเขาอาจมีชื่อ frontend / backend หรือ beeing เรียกว่าสิ่งอื่น ๆ ฉันมักจะเห็นพวกเขาเป็นสี่ขั้นตอน:

  1. ขั้นตอนแรกจะอ่านซอร์สโค้ดจริงและสร้างการแสดงภายใน ขั้นตอนนี้รู้ภาษาต้นฉบับจริง
  2. ขั้นตอนที่สองดูที่การเป็นตัวแทนภายในและทำการเพิ่มประสิทธิภาพเป็นจำนวนมาก ทุกวันนี้คอมไพเลอร์มักจะมองหาการทำให้โปรแกรมเร็วขึ้นและไม่สนใจถ้ามันใหญ่ขึ้น การปรับให้เหมาะสมจะทำในการเป็นตัวแทนภายใน น่าสนใจบางส่วนของสิ่งนี้อาจเป็นเรื่องทั่วไปสำหรับหลายภาษา
  3. ขั้นตอนที่สามใช้การแทนค่าภายในและสร้างรหัสจริงสำหรับ CPU ที่เลือก อาจมีเวอร์ชันที่แตกต่างกันหลายขั้นตอนนี้โดยกำหนดเป้าหมาย CPU-s ที่แตกต่างกัน ในความเป็นจริงคุณสามารถเขียนซอร์สโค้ดหนึ่งครั้งแล้วคอมไพล์มันสำหรับ CPUS-s อื่น
  4. การเตรียมการขั้นสุดท้ายสำหรับ "บรรจุภัณฑ์" โปรแกรม (ขั้นตอนนี้อาจเป็นตัวเชื่อมโยง)

การเขียนคอมไพเลอร์ที่ดีเป็นอาชีพที่มีทักษะสูง - การสร้างคอมไพเลอร์ภาษาของเล่นสามารถทำได้ในช่วงบ่ายโดยมือสมัครเล่น (หรือดีขึ้นอีกเล็กน้อย)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.