ภาษาแอสเซมบลีถูกแปลงเป็นภาษาเครื่องโดยแอสเซมเบลอร์ ทำไมคอมไพเลอร์จะแปลงภาษาระดับสูงเป็นชุดประกอบ? แปลงจากภาษาระดับสูงเป็นรหัสเครื่องโดยตรงไม่ได้หรือ
ภาษาแอสเซมบลีถูกแปลงเป็นภาษาเครื่องโดยแอสเซมเบลอร์ ทำไมคอมไพเลอร์จะแปลงภาษาระดับสูงเป็นชุดประกอบ? แปลงจากภาษาระดับสูงเป็นรหัสเครื่องโดยตรงไม่ได้หรือ
คำตอบ:
เหตุผลอื่นสำหรับคอมไพเลอร์ในการผลิตการประกอบมากกว่ารหัสเครื่องที่เหมาะสมคือ:
add eax,2
สามารถแปล83 c0 02
หรือขึ้นอยู่กับคำสั่งที่เกิดขึ้นล่าสุดเช่น66 83 c0 02
use16
คอมไพเลอร์มักจะแปลงรหัสระดับสูงเป็นภาษาเครื่องโดยตรง แต่สามารถสร้างในรูปแบบแยกส่วนเพื่อให้แบ็คเอนด์หนึ่งปล่อยรหัสเครื่องจักรและรหัสประกอบอื่น ๆ (เช่น GCC) ขั้นตอนการสร้างรหัสผลิต "รหัส" ซึ่งเป็นตัวแทนภายในของรหัสเครื่องซึ่งจะต้องถูกแปลงเป็นรูปแบบที่ใช้งานได้เช่นภาษาเครื่องหรือรหัสการประกอบ
ในอดีตมีคอมไพเลอร์ที่มีชื่อเสียงหลายตัวที่ทำโค้ดเครื่องจักรส่งออกโดยตรง อย่างไรก็ตามมีปัญหาในการทำเช่นนั้น โดยทั่วไปแล้วบางคนที่พยายามยืนยันว่าคอมไพเลอร์ทำงานอย่างถูกต้องจะตรวจสอบเอาต์พุตรหัสแอสเซมบลีได้ง่ายกว่ารหัสเครื่อง นอกจากนี้ยังเป็นไปได้ (และเป็นเรื่องธรรมดาในอดีต) เพื่อใช้คอมไพเลอร์ One-Pass C หรือ Pascal เพื่อสร้างไฟล์ภาษาแอสเซมบลีซึ่งสามารถประมวลผลได้โดยใช้แอสเซมเบลอร์สองรอบ การสร้างรหัสโดยตรงจะต้องใช้ทั้งคอมไพล์เลอร์ C หรือ Pascal หรือใช้คอมไพเลอร์ซิงเกิ้ลพาสตามด้วยวิธีการบางอย่างของการแบ็คแพ็ตไปข้างหน้ากระโดดหลังแพทช์ [ถ้าสภาพแวดล้อมรันไทม์ทำให้ขนาดของโปรแกรม จุดคงที่ คอมไพเลอร์สามารถเขียนรายการของโปรแกรมแก้ไขที่ส่วนท้ายของรหัสและมีรหัสเริ่มต้นใช้โปรแกรมปรับปรุงเหล่านั้นเมื่อรันไทม์ วิธีการเช่นนี้จะเพิ่มขนาดไฟล์เรียกใช้งานประมาณสี่ไบต์ต่อแพทช์จุด แต่จะปรับปรุงความเร็วการสร้างโปรแกรม]
หากเป้าหมายคือการมีคอมไพเลอร์ที่ทำงานได้อย่างรวดเร็วการสร้างรหัสโดยตรงสามารถทำงานได้ดี สำหรับโครงการส่วนใหญ่ค่าใช้จ่ายในการสร้างรหัสแอสเซมบลีและการประกอบมันไม่ได้เป็นปัญหาใหญ่ในปัจจุบัน การมีคอมไพเลอร์จะสร้างโค้ดในรูปแบบที่สามารถโต้ตอบได้ดีกับโค้ดที่คอมไพเลอร์สร้างขึ้นโดยทั่วไปแล้วจะมีประโยชน์มากพอที่จะแสดงให้เห็นถึงการเพิ่มขึ้นของเวลาการคอมไพล์
แม้แต่แพลตฟอร์มที่ใช้ชุดคำสั่งเดียวกันอาจมีรูปแบบไฟล์อ็อบเจ็กต์ที่เปลี่ยนตำแหน่งได้แตกต่างกัน ฉันคิดได้ว่า "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
โดยทั่วไปแล้วคอมไพเลอร์จะทำงานภายในตามลำดับขั้นตอน แต่ละคำสั่งจะถูกแทนด้วยโครงสร้างข้อมูลที่แสดงชื่อการดำเนินการตัวถูกดำเนินการและอื่น ๆ เมื่อตัวถูกดำเนินการอยู่ที่อยู่เหล่านั้นมักจะเป็นการอ้างอิงเชิงสัญลักษณ์ไม่ใช่ค่าที่เป็นรูปธรรม
แอสเซมเบลอร์เอาต์พุตค่อนข้างง่าย มันเป็นเรื่องของการรวบรวมโครงสร้างข้อมูลภายในคอมไพเลอร์และทิ้งมันไปยังไฟล์ข้อความในรูปแบบเฉพาะ เอาต์พุตแอสเซมเบลอร์ยังค่อนข้างง่ายต่อการอ่านซึ่งมีประโยชน์เมื่อคุณต้องการตรวจสอบสิ่งที่คอมไพเลอร์กำลังทำอยู่
การส่งออกไฟล์วัตถุไบนารีนั้นทำงานได้ดีกว่ามาก ผู้เขียนคอมไพเลอร์จำเป็นต้องรู้ว่าคำสั่งทั้งหมดจะถูกเข้ารหัสอย่างไร (ซึ่งอาจอยู่ห่างจากเรื่องเล็กน้อยในบาง CPUS) พวกเขาจำเป็นต้องแปลงการอ้างอิงเชิงสัญลักษณ์บางส่วนไปเป็นที่อยู่เชิงสัมพันธ์ของโปรแกรมเคาน์เตอร์และอื่น ๆ ในรูปแบบของข้อมูลเมตาในไฟล์วัตถุไบนารี . พวกเขาจำเป็นต้องเขียนทุกอย่างออกมาในรูปแบบที่เป็นระบบเฉพาะสูง
ใช่คุณสามารถสร้างคอมไพเลอร์ที่สามารถส่งออกวัตถุไบนารีโดยตรงโดยไม่ต้องเขียนแอสเซมเบลอร์เป็นขั้นตอนกลาง คำถามเช่นหลายสิ่งหลายอย่างในการพัฒนาซอฟต์แวร์คือการลดเวลาในการรวบรวมนั้นคุ้มค่ากับการพัฒนาและบำรุงรักษาเพิ่มเติมหรือไม่
คอมไพเลอร์ฉันคุ้นเคยกับ (freepascal) สามารถส่งออกแอสเซมเบลอร์ในทุกแพลตฟอร์ม แต่สามารถส่งออกวัตถุไบนารีโดยตรงโดยตรงในส่วนย่อยของแพลตฟอร์ม
คอมไพเลอร์ควรจะสามารถสร้างเอาท์พุทแอสเซมเบลอร์นอกเหนือจากรหัส 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 ที่คอมไพเลอร์ไม่ได้
ทำไม???