ฉันต้องการทราบความหมายเชิงลึกและการทำงานของคอมไพเลอร์ตัวเชื่อมโยงและตัวโหลด เมื่ออ้างอิงถึงภาษาใด ๆ ควรใช้ c ++
ฉันต้องการทราบความหมายเชิงลึกและการทำงานของคอมไพเลอร์ตัวเชื่อมโยงและตัวโหลด เมื่ออ้างอิงถึงภาษาใด ๆ ควรใช้ c ++
คำตอบ:
=====> COMPILATION PROCESS <======
|
|----> Input is Source file(.c)
|
V
+=================+
| |
| C Preprocessor |
| |
+=================+
|
| ---> Pure C file ( comd:cc -E <file.name> )
|
V
+=================+
| |
| Lexical Analyzer|
| |
+-----------------+
| |
| Syntax Analyzer |
| |
+-----------------+
| |
| Semantic Analyze|
| |
+-----------------+
| |
| Pre Optimization|
| |
+-----------------+
| |
| Code generation |
| |
+-----------------+
| |
| Post Optimize |
| |
+=================+
|
|---> Assembly code (comd: cc -S <file.name> )
|
V
+=================+
| |
| Assembler |
| |
+=================+
|
|---> Object file (.obj) (comd: cc -c <file.name>)
|
V
+=================+
| Linker |
| and |
| loader |
+=================+
|
|---> Executable (.Exe/a.out) (com:cc <file.name> )
|
V
Executable file(a.out)
การประมวลผลล่วงหน้า C เป็นขั้นตอนแรกในการคอมไพล์ จัดการ:
#define
งบ#include
งบวัตถุประสงค์ของหน่วยคือการแปลงไฟล์ต้นฉบับ C เป็นไฟล์รหัส Pure C
มีหกขั้นตอนในหน่วย:
มันรวมอักขระในไฟล์ต้นฉบับเพื่อสร้าง "TOKEN" โทเค็นคือชุดอักขระที่ไม่มี "ช่องว่าง" "แท็บ" และ "บรรทัดใหม่" ดังนั้นจึงเรียกหน่วยการคอมไพล์นี้ว่า "TOKENIZER" นอกจากนี้ยังลบความคิดเห็นสร้างตารางสัญลักษณ์และรายการตารางการย้าย
หน่วยนี้ตรวจสอบไวยากรณ์ในรหัส สำหรับเช่น:
{
int a;
int b;
int c;
int d;
d = a + b - c * ;
}
โค้ดด้านบนจะสร้างข้อผิดพลาดในการแยกวิเคราะห์เนื่องจากสมการไม่สมดุล หน่วยนี้ตรวจสอบสิ่งนี้ภายในโดยการสร้างโครงสร้างตัวแยกวิเคราะห์ดังนี้:
=
/ \
d -
/ \
+ *
/ \ / \
a b c ?
ดังนั้นจึงเรียกหน่วยนี้ว่า PARSER
หน่วยนี้ตรวจสอบความหมายในงบ สำหรับเช่น:
{
int i;
int *p;
p = i;
-----
-----
-----
}
โค้ดด้านบนสร้างข้อผิดพลาด "การกำหนดประเภทที่เข้ากันไม่ได้"
หน่วยนี้ไม่ขึ้นอยู่กับซีพียูกล่าวคือมีการเพิ่มประสิทธิภาพสองประเภท
หน่วยนี้ปรับรหัสให้เหมาะสมในรูปแบบต่อไปนี้:
สำหรับเช่น:
{
int a = 10;
if ( a > 5 ) {
/*
...
*/
} else {
/*
...
*/
}
}
ที่นี่คอมไพลเลอร์รู้ค่า 'a' ในเวลาคอมไพล์ดังนั้นจึงรู้ด้วยว่าเงื่อนไข if เป็นจริงเสมอ ดังนั้นจึงกำจัดส่วนอื่นในรหัส
สำหรับเช่น:
{
int a, b, c;
int x, y;
/*
...
*/
x = a + b;
y = a + b + c;
/*
...
*/
}
สามารถปรับให้เหมาะสมได้ดังนี้:
{
int a, b, c;
int x, y;
/*
...
*/
x = a + b;
y = x + c; // a + b is replaced by x
/*
...
*/
}
สำหรับเช่น:
{
int a;
for (i = 0; i < 1000; i++ ) {
/*
...
*/
a = 10;
/*
...
*/
}
}
ในโค้ดด้านบนหาก 'a' เป็นแบบโลคัลและไม่ได้ใช้ในลูปก็สามารถปรับให้เหมาะสมได้ดังนี้:
{
int a;
a = 10;
for (i = 0; i < 1000; i++ ) {
/*
...
*/
}
}
ที่นี่คอมไพลเลอร์จะสร้างรหัสแอสเซมบลีเพื่อให้ตัวแปรที่ใช้บ่อยมากขึ้นถูกเก็บไว้ในรีจิสเตอร์
ที่นี่การปรับให้เหมาะสมขึ้นอยู่กับ CPU สมมติว่ามีการกระโดดมากกว่าหนึ่งรหัสจากนั้นจะถูกแปลงเป็นหนึ่งใน:
-----
jmp:<addr1>
<addr1> jmp:<addr2>
-----
-----
การควบคุมจะกระโดดไปที่
จากนั้นขั้นตอนสุดท้ายคือการเชื่อมโยง (ซึ่งสร้างไฟล์ปฏิบัติการหรือไลบรารี) เมื่อเรียกใช้งานได้ไลบรารีที่ต้องการคือ Loaded
การแสดง ASCII:
[Source Code] ---> Compiler ---> [Object code] --*
|
[Source Code] ---> Compiler ---> [Object code] --*--> Linker --> [Executable] ---> Loader
| |
[Source Code] ---> Compiler ---> [Object code] --* |
| |
[Library file]--* V
[Running Executable in Memory]
หวังว่านี่จะช่วยคุณได้อีกเล็กน้อย
ขั้นแรกให้ดูแผนภาพนี้:
(img source->internet)
คุณสร้างโค้ดและบันทึกไฟล์ (ซอร์สโค้ด) จากนั้น
การประมวลผลล่วงหน้าประมวลผลล่วงหน้า: - ตามชื่อที่แนะนำไม่ใช่ส่วนหนึ่งของการรวบรวม พวกเขาสั่งให้คอมไพเลอร์ทำการประมวลผลล่วงหน้าที่จำเป็นก่อนการคอมไพล์จริง คุณสามารถเรียกเฟสนี้ว่า Text Substitution หรือตีความคำสั่งพรีโปรเซสเซอร์พิเศษที่แสดงโดย #
การรวบรวม : - การรวบรวมเป็นกระบวนการที่โปรแกรมที่เขียนด้วยภาษาหนึ่งได้รับการแปลเป็นภาษาเป้าหมายอื่น หากมีข้อผิดพลาดบางอย่างคอมไพลเลอร์จะตรวจพบและรายงาน
Assemble : - Assemble code จะถูกแปลเป็นรหัสเครื่อง คุณสามารถเรียกแอสเซมเบลอร์ว่าเป็นคอมไพเออร์ประเภทพิเศษ
การเชื่อมโยง : - หากชิ้นส่วนของโค้ดเหล่านี้ต้องการเชื่อมโยงซอร์สไฟล์อื่น ๆ ให้ลิงค์เกอร์เชื่อมโยงเพื่อทำให้เป็นไฟล์ปฏิบัติการ
มีกระบวนการมากมายที่เกิดขึ้นหลังจากนั้น ใช่คุณเดาถูกที่นี่หน้าที่ของตัวโหลด:
Loader : - โหลดโค้ดปฏิบัติการลงในหน่วยความจำ มีการสร้างโปรแกรมและกองข้อมูลการลงทะเบียนเริ่มต้น
ข้อมูลเพิ่มเติมเล็กน้อย: - http://www.geeksforgeeks.org/memory-layout-of-c-program/คุณสามารถดูเค้าโครงหน่วยความจำได้ที่นั่น
คอมไพเลอร์: เป็นโปรแกรมที่แปลโปรแกรมภาษาระดับสูงให้เป็นโปรแกรมภาษาเครื่อง คอมไพเลอร์ฉลาดกว่าแอสเซมเบลอร์ มันตรวจสอบขีด จำกัด ช่วงข้อผิดพลาดและอื่น ๆ ทุกชนิด แต่เวลาในการรันโปรแกรมจะมากกว่าและใช้หน่วยความจำส่วนใหญ่ มีความเร็วช้า เนื่องจากคอมไพเลอร์ผ่านโปรแกรมทั้งหมดแล้วจึงแปลโปรแกรมทั้งหมดเป็นรหัสเครื่อง หากคอมไพเลอร์ทำงานบนคอมพิวเตอร์และสร้างรหัสเครื่องสำหรับคอมพิวเตอร์เครื่องเดียวกันจะเรียกว่าคอมไพเลอร์ตัวเองหรือคอมไพเลอร์ประจำ ในทางกลับกันถ้าคอมไพเลอร์ทำงานบนคอมพิวเตอร์และสร้างรหัสเครื่องสำหรับคอมพิวเตอร์เครื่องอื่นจะเรียกว่าคอมไพเลอร์ข้าม
Linker: ในภาษาระดับสูงไฟล์ส่วนหัวหรือไลบรารีในตัวบางไฟล์จะถูกเก็บไว้ ไลบรารีเหล่านี้ถูกกำหนดไว้ล่วงหน้าและประกอบด้วยฟังก์ชันพื้นฐานที่จำเป็นสำหรับการเรียกใช้งานโปรแกรม ฟังก์ชันเหล่านี้เชื่อมโยงกับไลบรารีโดยโปรแกรมที่เรียกว่า Linker หากตัวเชื่อมโยงไม่พบไลบรารีของฟังก์ชันจะแจ้งไปยังคอมไพเลอร์จากนั้นคอมไพเลอร์จะสร้างข้อผิดพลาด คอมไพเลอร์จะเรียกใช้ตัวเชื่อมโยงโดยอัตโนมัติเป็นขั้นตอนสุดท้ายในการคอมไพล์โปรแกรม ไม่ได้สร้างขึ้นในไลบรารี แต่ยังเชื่อมโยงฟังก์ชันที่ผู้ใช้กำหนดกับไลบรารีที่ผู้ใช้กำหนด โดยปกติโปรแกรมที่ยาวกว่าจะแบ่งออกเป็นโปรแกรมย่อยขนาดเล็กที่เรียกว่าโมดูล และโมดูลเหล่านี้จะต้องรวมกันเพื่อดำเนินการโปรแกรม ขั้นตอนการรวมโมดูลจะกระทำโดยตัวเชื่อมโยง
Loader: Loader เป็นโปรแกรมที่โหลดรหัสเครื่องของโปรแกรมลงในหน่วยความจำระบบ ในคอมพิวเตอร์โหลดเดอร์เป็นส่วนหนึ่งของระบบปฏิบัติการที่มีหน้าที่โหลดโปรแกรม เป็นหนึ่งในขั้นตอนสำคัญในกระบวนการเริ่มต้นโปรแกรม เนื่องจากวางโปรแกรมไว้ในหน่วยความจำและเตรียมไว้สำหรับการดำเนินการ การโหลดโปรแกรมเกี่ยวข้องกับการอ่านเนื้อหาของไฟล์ปฏิบัติการลงในหน่วยความจำ เมื่อการโหลดเสร็จสิ้นระบบปฏิบัติการจะเริ่มโปรแกรมโดยส่งผ่านการควบคุมไปยังโค้ดโปรแกรมที่โหลด ระบบปฏิบัติการทั้งหมดที่รองรับการโหลดโปรแกรมมีตัวโหลด ในหลาย ๆ ระบบปฏิบัติการตัวโหลดจะอยู่ในหน่วยความจำอย่างถาวร
Wikipedia ควรมีคำตอบที่ดีนี่คือความคิดของฉัน:
*
*
Linkers and Loadersจาก LinuxJournal อธิบายแนวคิดนี้อย่างชัดเจน นอกจากนี้ยังอธิบายว่าชื่อคลาสสิก a.out เกิดขึ้นได้อย่างไร (เอาท์พุทแอสเซมเบลอร์)
สรุปสั้น ๆ
c program --> [compiler] --> objectFile --> [linker] --> executable file (say, a.out)
เรามีไฟล์ปฏิบัติการตอนนี้ให้ไฟล์นี้กับเพื่อนของคุณหรือให้กับลูกค้าของคุณที่ต้องการซอฟต์แวร์นี้ :)
เมื่อพวกเขาเรียกใช้ซอฟต์แวร์นี้ให้พูดโดยพิมพ์ในบรรทัดคำสั่ง. / a.out
execute in command line ./a.out --> [Loader] --> [execve] --> program is loaded in memory
เมื่อโหลดโปรแกรมลงในหน่วยความจำแล้วการควบคุมจะถูกโอนไปยังโปรแกรมนี้โดยทำให้พีซี (ตัวนับโปรแกรม) ชี้ไปที่คำสั่งแรกของ a.out
มันจะอ่านซอร์สไฟล์ซึ่งอาจเป็นประเภท. c หรือ. cpp เป็นต้นและแปลเป็นไฟล์. o เรียกว่าอ็อบเจ็กต์ไฟล์
มันรวมไฟล์. o หลายไฟล์ซึ่งอาจสร้างขึ้นสำหรับไฟล์ต้นฉบับหลายไฟล์เป็นไฟล์ปฏิบัติการ (รูปแบบ ELF ใน GCC) การเชื่อมโยงมีสองประเภท:
โปรแกรมที่โหลดไฟล์ปฏิบัติการไปยังหน่วยความจำหลักของเครื่อง
สำหรับการศึกษาในรายละเอียดเกี่ยวกับทั้งสามขั้นตอนของการทำงานของโปรแกรมใน Linux โปรดอ่านบทความนี้
การเปลี่ยนแปลงคอมไพเลอร์จะตรวจสอบซอร์สโค้ดของคุณเพื่อหาข้อผิดพลาดและเปลี่ยนเป็นรหัสออบเจ็กต์นี่คือรหัสที่ระบบปฏิบัติการเรียกใช้
คุณมักจะไม่เขียนโปรแกรมทั้งหมดในไฟล์เดียวดังนั้นลิงค์เกอร์จะลิงก์ไฟล์อ็อบเจ็กต์โค้ดทั้งหมดของคุณ
โปรแกรมของคุณจะไม่ถูกเรียกใช้งานเว้นแต่จะอยู่ในหน่วยความจำหลัก
Linker & Interpreter เป็นล่ามที่รับโค้ดทีละบรรทัดและดำเนินการทีละบรรทัด
คอมไพเลอร์ จะแปลงซอร์สโค้ดเป็นอ็อบเจ็กต์โค้ด
Linker มันรวมไฟล์อ็อบเจ็กต์หลายไฟล์ไว้ในไฟล์โปรแกรมปฏิบัติการไฟล์เดียว
Loader มันโหลดไฟล์ปฏิบัติการลงในหน่วยความจำหลัก
คอมไพเลอร์เป็นโปรแกรมพิเศษที่ประมวลผลคำสั่งที่เขียนด้วยภาษาโปรแกรมเฉพาะและเปลี่ยนเป็นภาษาเครื่องหรือ "รหัส" ที่โปรเซสเซอร์ของคอมพิวเตอร์ใช้
คอมไพเลอร์แปลบรรทัดของโค้ดจากภาษาโปรแกรมเป็นภาษาเครื่อง
Linkerสร้างลิงค์ระหว่างสองโปรแกรม
Loaderโหลดโปรแกรมลงในหน่วยความจำในฐานข้อมูลหลักโปรแกรม ฯลฯ
คอมไพเลอร์: เป็นซอฟต์แวร์ระบบที่แก้ไขข้อผิดพลาดของโปรแกรมไฟล์ออบเจ็กต์ข้อความ ฯลฯ
Linker: เป็นซอฟต์แวร์ระบบที่รวมไฟล์ออบเจ็กต์อย่างน้อยหนึ่งไฟล์และรหัสไลบรารีบางส่วนที่เป็นไปได้ในไลบรารีบางไลบรารี
Loader: โปรแกรมที่โหลดไฟล์ปฏิบัติการไปยังหน่วยความจำหลักของเครื่อง