ทำไมคอมไพเลอร์จึงสร้างรหัสชุดประกอบ?


19

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

คำตอบ:


22

เหตุผลอื่นสำหรับคอมไพเลอร์ในการผลิตการประกอบมากกว่ารหัสเครื่องที่เหมาะสมคือ:

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

เหตุใดภาษาแอสเซมบลีจึงมีประสิทธิภาพมากแม้ว่าจะเขียนด้วยภาษาอังกฤษและตัวประมวลผลเข้าใจอย่างไร
CODERSAM

3
@CODERSAM Assembly เป็นภาษาทางการไม่ใช่ภาษาธรรมชาติ มันใกล้เคียงกับภาษาเครื่องมาก ดังนั้นการแปลไม่แนะนำความไร้ประสิทธิภาพ
Martin Berger

เมื่อคุณพูดว่า "ใกล้เคียงกับภาษาเครื่อง" นั่นแปลว่าอะไร? ฉันสับสนกับสิ่งนี้จริงๆ!
CODERSAM

2
@CODERSAM ความหมายที่แม่นยำนั้นซับซ้อน แต่สิ่งที่คล้ายกับโฮโมมอร์ฟิซึมในพีชคณิต เมื่อคุณแปลให้พูดว่า "เพิ่ม eax, # 2" ซึ่งเป็นชุดประกอบ x86 คุณสามารถแปลเป็น d7f5 (หรือรหัส op-code อื่น ๆ ) ได้ทันทีโดยไม่ต้องมองบริบทใด ๆ โดยไม่ต้องเพิ่มอะไรเข้าไปอีก การชุมนุมไม่มีสิ่งที่เป็นนามธรรม
Martin Berger

1
"ชุดประกอบไม่มีสิ่งที่เป็นนามธรรม" - ฉันว่าชื่อป้ายกำกับเป็นสิ่งที่เป็นนามธรรมอยู่แล้ว (จากออฟเซ็ต) นอกจากนี้บริบทจะมีบทบาท: เช่นadd eax,2สามารถแปล83 c0 02หรือขึ้นอยู่กับคำสั่งที่เกิดขึ้นล่าสุดเช่น66 83 c0 02 use16
Ruslan

15

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


นอกจากนี้หากแหล่งที่มาอาจมีรหัสแอสเซมบลีบางส่วนจะต้องมีกลไกในการแปลแอสเซมบลีอินไลน์นั้น
Paul A. Clayton

เหตุใดภาษาแอสเซมบลีจึงมีประสิทธิภาพมากแม้ว่าจะเขียนด้วยภาษาอังกฤษและตัวประมวลผลเข้าใจอย่างไร
CODERSAM

1
ภาษาแอสเซมบลีคือคำอธิบาย "ภาษาอังกฤษ" ของรหัสเครื่อง
Yuval Filmus

11

ในอดีตมีคอมไพเลอร์ที่มีชื่อเสียงหลายตัวที่ทำโค้ดเครื่องจักรส่งออกโดยตรง อย่างไรก็ตามมีปัญหาในการทำเช่นนั้น โดยทั่วไปแล้วบางคนที่พยายามยืนยันว่าคอมไพเลอร์ทำงานอย่างถูกต้องจะตรวจสอบเอาต์พุตรหัสแอสเซมบลีได้ง่ายกว่ารหัสเครื่อง นอกจากนี้ยังเป็นไปได้ (และเป็นเรื่องธรรมดาในอดีต) เพื่อใช้คอมไพเลอร์ One-Pass C หรือ Pascal เพื่อสร้างไฟล์ภาษาแอสเซมบลีซึ่งสามารถประมวลผลได้โดยใช้แอสเซมเบลอร์สองรอบ การสร้างรหัสโดยตรงจะต้องใช้ทั้งคอมไพล์เลอร์ C หรือ Pascal หรือใช้คอมไพเลอร์ซิงเกิ้ลพาสตามด้วยวิธีการบางอย่างของการแบ็คแพ็ตไปข้างหน้ากระโดดหลังแพทช์ [ถ้าสภาพแวดล้อมรันไทม์ทำให้ขนาดของโปรแกรม จุดคงที่ คอมไพเลอร์สามารถเขียนรายการของโปรแกรมแก้ไขที่ส่วนท้ายของรหัสและมีรหัสเริ่มต้นใช้โปรแกรมปรับปรุงเหล่านั้นเมื่อรันไทม์ วิธีการเช่นนี้จะเพิ่มขนาดไฟล์เรียกใช้งานประมาณสี่ไบต์ต่อแพทช์จุด แต่จะปรับปรุงความเร็วการสร้างโปรแกรม]

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


1

แม้แต่แพลตฟอร์มที่ใช้ชุดคำสั่งเดียวกันอาจมีรูปแบบไฟล์อ็อบเจ็กต์ที่เปลี่ยนตำแหน่งได้แตกต่างกัน ฉันคิดได้ว่า "a.out" (ต้น UNIX), OMF, MZ (MS-DOS EXE), NE (Windows 16 บิต), COFF (UNIX System V), Mach-O (OS X และ iOS) และ ELF (Linux และอื่น ๆ ) รวมถึงตัวแปรต่างๆเช่น XCOFF (AIX), ECOFF (SGI) และ COFF-based Portable Executable (PE) บน Windows แบบ 32 บิต คอมไพเลอร์ที่สร้างภาษาแอสเซมบลีไม่จำเป็นต้องรู้อะไรมากเกี่ยวกับรูปแบบไฟล์ออบเจกต์ทำให้แอสเซมเบลอร์และตัวเชื่อมโยงสามารถห่อหุ้มความรู้นั้นในกระบวนการแยกต่างหาก

ดูเพิ่มเติมความแตกต่างระหว่าง OMF และ COFFบน Stack Overflow


1

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

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

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

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

คอมไพเลอร์ฉันคุ้นเคยกับ (freepascal) สามารถส่งออกแอสเซมเบลอร์ในทุกแพลตฟอร์ม แต่สามารถส่งออกวัตถุไบนารีโดยตรงโดยตรงในส่วนย่อยของแพลตฟอร์ม


1

คอมไพเลอร์ควรจะสามารถสร้างเอาท์พุทแอสเซมเบลอร์นอกเหนือจากรหัส relocatable ปกติเพื่อประโยชน์ของโปรแกรมเมอร์

มีอยู่ครั้งหนึ่งที่ฉันไม่พบข้อผิดพลาดในโปรแกรม C ที่ทำงานบน Unix System V บนเครื่อง LSI-11 ดูเหมือนจะไม่มีอะไรทำงาน ในที่สุดด้วยความสิ้นหวังฉันมีคอมไพเลอร์ C แบบ protable ขับถ่ายเวอร์ชั่นแปลของแอสเซมเบลอร์ ในที่สุดฉันก็พบข้อผิดพลาด! คอมไพเลอร์ได้จัดสรรการลงทะเบียนมากกว่าที่มีอยู่ในเครื่อง! (คอมไพเลอร์จัดสรรการลงทะเบียน R0 ถึง R8 บนเครื่องที่ลงทะเบียนเพียง R0 ถึง R7 เท่านั้น) ฉันจัดการเพื่อแก้ไขข้อบกพร่องในคอมไพเลอร์และโปรแกรมทำงานได้

ข้อดีอีกประการของการมีเอาต์พุตแอสเซมเบลอร์คือการพยายามใช้ไลบรารี "มาตรฐาน" ที่ใช้พารามิเตอร์การส่งผ่านโปรโตคอลที่แตกต่างกัน หลังจากนั้นคอมไพเลอร์ C อนุญาตให้ฉันตั้งโพรโทคอลด้วยพารามิเตอร์ ("ปาสคาล" จะทำให้คอมไพเลอร์เพิ่มพารามิเตอร์ตามลำดับที่ให้ไว้ซึ่งตรงข้ามกับมาตรฐาน C ของการกลับคำสั่ง)

ประโยชน์อีกประการหนึ่งคือการอนุญาตให้โปรแกรมเมอร์เห็นว่างานของเขาเรียบเรียงอะไรอยู่ คำสั่ง C อย่างง่ายใช้เวลาประมาณ 44 คำสั่งเครื่อง ค่าจะถูกโหลดจากหน่วยความจำแล้วทิ้งอย่างรวดเร็ว ฯลฯ ฯลฯ ฯลฯ ...

ฉันเองเชื่อว่าการมีคอมไพเลอร์แทนโมดูลวัตถุที่เปลี่ยนตำแหน่งได้นั้นโง่จริงๆ ในขณะที่คอมไพล์โปรแกรมของคุณคอมไพเลอร์จะรวบรวมข้อมูลมากมายเกี่ยวกับโปรแกรมของคุณ มันมักจะเก็บข้อมูลทั้งหมดนี้ในสิ่งที่เรียกว่าตารางสัญลักษณ์ หลังจาก excreting รหัสแอสเซมเบลอร์มันจะโยนตารางข้อมูลทั้งหมดนี้ แอสเซมเบลอร์จะตรวจสอบโค้ดที่ถูกขับออกมาและรวบรวมข้อมูลบางส่วนที่คอมไพเลอร์มีอยู่แล้ว อย่างไรก็ตามแอสเซมเบลอร์ไม่รู้อะไรเกี่ยวกับ If statement of For statement หรือ while statement ดังนั้นข้อมูลทั้งหมดนี้จะหายไป จากนั้นแอสเซมเบลอร์จะสร้างโมดูลวัตถุ relocatable ที่คอมไพเลอร์ไม่ได้

ทำไม???

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