คอมไพเลอร์ลิงค์เกอร์ตัวโหลดคืออะไร?


107

ฉันต้องการทราบความหมายเชิงลึกและการทำงานของคอมไพเลอร์ตัวเชื่อมโยงและตัวโหลด เมื่ออ้างอิงถึงภาษาใด ๆ ควรใช้ c ++


คำตอบ:


186
=====> 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 พรีโปรเซสเซอร์: -

การประมวลผลล่วงหน้า C เป็นขั้นตอนแรกในการคอมไพล์ จัดการ:

  1. #define งบ
  2. #include งบ
  3. งบเงื่อนไข
  4. มาโคร

วัตถุประสงค์ของหน่วยคือการแปลงไฟล์ต้นฉบับ C เป็นไฟล์รหัส Pure C

การรวบรวม C:

มีหกขั้นตอนในหน่วย:

1) เครื่องวิเคราะห์คำศัพท์:

มันรวมอักขระในไฟล์ต้นฉบับเพื่อสร้าง "TOKEN" โทเค็นคือชุดอักขระที่ไม่มี "ช่องว่าง" "แท็บ" และ "บรรทัดใหม่" ดังนั้นจึงเรียกหน่วยการคอมไพล์นี้ว่า "TOKENIZER" นอกจากนี้ยังลบความคิดเห็นสร้างตารางสัญลักษณ์และรายการตารางการย้าย

2) เครื่องวิเคราะห์วากยสัมพันธ์:

หน่วยนี้ตรวจสอบไวยากรณ์ในรหัส สำหรับเช่น:

{
    int a;
    int b;
    int c;
    int d;

    d = a + b - c *   ;
}

โค้ดด้านบนจะสร้างข้อผิดพลาดในการแยกวิเคราะห์เนื่องจากสมการไม่สมดุล หน่วยนี้ตรวจสอบสิ่งนี้ภายในโดยการสร้างโครงสร้างตัวแยกวิเคราะห์ดังนี้:

                            =
                          /   \
                        d       -
                              /     \
                            +           *
                          /   \       /   \
                        a       b   c       ?

ดังนั้นจึงเรียกหน่วยนี้ว่า PARSER

3) เครื่องวิเคราะห์ความหมาย:

หน่วยนี้ตรวจสอบความหมายในงบ สำหรับเช่น:

{
    int i;
    int *p;

    p = i;
    -----
    -----
    -----
}

โค้ดด้านบนสร้างข้อผิดพลาด "การกำหนดประเภทที่เข้ากันไม่ได้"

4) การเพิ่มประสิทธิภาพล่วงหน้า:

หน่วยนี้ไม่ขึ้นอยู่กับซีพียูกล่าวคือมีการเพิ่มประสิทธิภาพสองประเภท

  1. Preoptimization (CPU อิสระ)
  2. Postoptimization (ขึ้นอยู่กับ CPU)

หน่วยนี้ปรับรหัสให้เหมาะสมในรูปแบบต่อไปนี้:

  • I) การกำจัดรหัสตาย
  • II) การกำจัดรหัสย่อย
  • III) การเพิ่มประสิทธิภาพลูป

I) การกำจัดรหัสตาย:

สำหรับเช่น:

{
    int a = 10;
    if ( a > 5 ) {
        /*
        ...
        */
    } else {
       /*
       ...
       */
    }
}

ที่นี่คอมไพลเลอร์รู้ค่า 'a' ในเวลาคอมไพล์ดังนั้นจึงรู้ด้วยว่าเงื่อนไข if เป็นจริงเสมอ ดังนั้นจึงกำจัดส่วนอื่นในรหัส

II) การกำจัดรหัสย่อย:

สำหรับเช่น:

{
    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

    /*
     ...
    */
}

III) การเพิ่มประสิทธิภาพลูป:

สำหรับเช่น:

{
    int a;
    for (i = 0; i < 1000; i++ ) {

    /*
     ...
    */

    a = 10;

    /*
     ...
    */
    }
}

ในโค้ดด้านบนหาก 'a' เป็นแบบโลคัลและไม่ได้ใช้ในลูปก็สามารถปรับให้เหมาะสมได้ดังนี้:

{
    int a;
    a = 10;
    for (i = 0; i < 1000; i++ ) {
        /*
        ...
        */
    }
}

5) การสร้างรหัส:

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

6) การเพิ่มประสิทธิภาพภายหลัง:

ที่นี่การปรับให้เหมาะสมขึ้นอยู่กับ CPU สมมติว่ามีการกระโดดมากกว่าหนึ่งรหัสจากนั้นจะถูกแปลงเป็นหนึ่งใน:

            -----
        jmp:<addr1>
<addr1> jmp:<addr2>
            -----
            -----

การควบคุมจะกระโดดไปที่

จากนั้นขั้นตอนสุดท้ายคือการเชื่อมโยง (ซึ่งสร้างไฟล์ปฏิบัติการหรือไลบรารี) เมื่อเรียกใช้งานได้ไลบรารีที่ต้องการคือ Loaded


6
ฉันไม่แน่ใจว่าทำไมยังไม่มีใครชี้ให้เห็น แต่ตัวเชื่อมโยงและตัวโหลดไม่ได้อยู่ในขั้นตอนเดียวกัน การเชื่อมโยงเป็นส่วนหนึ่งของการคอมไพล์ในขณะที่การโหลดเป็นส่วนหนึ่งของ (ก่อนหน้า) ที่รันโปรแกรม
SimpleGuy

7) Assembler อยู่ที่ไหนและที่สำคัญที่สุด 8) Linker และ 9) Loader ที่ถูกถาม?

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

การแสดง 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]

2
คำอธิบายนี้ตรงไปตรงมา คุณควรพิจารณาเป็นวิทยากร ขอบคุณ
0.sh

ขอขอบคุณที่ไม่หลีกเลี่ยงที่จะตอบเกี่ยวกับตัวเชื่อมโยงและตัวโหลด!

29

หวังว่านี่จะช่วยคุณได้อีกเล็กน้อย

ขั้นแรกให้ดูแผนภาพนี้:

                         (img source->internet)

แหล่งที่มา -> อินเทอร์เน็ต

คุณสร้างโค้ดและบันทึกไฟล์ (ซอร์สโค้ด) จากนั้น

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

การรวบรวม : - การรวบรวมเป็นกระบวนการที่โปรแกรมที่เขียนด้วยภาษาหนึ่งได้รับการแปลเป็นภาษาเป้าหมายอื่น หากมีข้อผิดพลาดบางอย่างคอมไพลเลอร์จะตรวจพบและรายงาน

Assemble : - Assemble code จะถูกแปลเป็นรหัสเครื่อง คุณสามารถเรียกแอสเซมเบลอร์ว่าเป็นคอมไพเออร์ประเภทพิเศษ

การเชื่อมโยง : - หากชิ้นส่วนของโค้ดเหล่านี้ต้องการเชื่อมโยงซอร์สไฟล์อื่น ๆ ให้ลิงค์เกอร์เชื่อมโยงเพื่อทำให้เป็นไฟล์ปฏิบัติการ

มีกระบวนการมากมายที่เกิดขึ้นหลังจากนั้น ใช่คุณเดาถูกที่นี่หน้าที่ของตัวโหลด:

Loader : - โหลดโค้ดปฏิบัติการลงในหน่วยความจำ มีการสร้างโปรแกรมและกองข้อมูลการลงทะเบียนเริ่มต้น

ข้อมูลเพิ่มเติมเล็กน้อย: - http://www.geeksforgeeks.org/memory-layout-of-c-program/คุณสามารถดูเค้าโครงหน่วยความจำได้ที่นั่น


15

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

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

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


14

Wikipedia ควรมีคำตอบที่ดีนี่คือความคิดของฉัน:

  • คอมไพเลอร์: อ่านแหล่งที่มา something.c เขียน something.o object
  • Linker: รวมไฟล์ * .o หลายไฟล์ลงในโปรแกรมปฏิบัติการ
  • Loader: รหัสที่โหลดไฟล์ปฏิบัติการลงในหน่วยความจำและเริ่มทำงาน

4

*

อธิบายเกี่ยวกับระบบที่ใช้ linux / unix แม้ว่าจะเป็นแนวคิดพื้นฐานสำหรับระบบคอมพิวเตอร์อื่น ๆ ทั้งหมด

*

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


4

คอมไพเลอร์:

มันจะอ่านซอร์สไฟล์ซึ่งอาจเป็นประเภท. c หรือ. cpp เป็นต้นและแปลเป็นไฟล์. o เรียกว่าอ็อบเจ็กต์ไฟล์

ลิงค์เกอร์:

มันรวมไฟล์. o หลายไฟล์ซึ่งอาจสร้างขึ้นสำหรับไฟล์ต้นฉบับหลายไฟล์เป็นไฟล์ปฏิบัติการ (รูปแบบ ELF ใน GCC) การเชื่อมโยงมีสองประเภท:

  • การเชื่อมโยงแบบคงที่
  • การเชื่อมโยงแบบไดนามิก

รถตัก:

โปรแกรมที่โหลดไฟล์ปฏิบัติการไปยังหน่วยความจำหลักของเครื่อง


สำหรับการศึกษาในรายละเอียดเกี่ยวกับทั้งสามขั้นตอนของการทำงานของโปรแกรมใน Linux โปรดอ่านบทความนี้


1

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

คุณมักจะไม่เขียนโปรแกรมทั้งหมดในไฟล์เดียวดังนั้นลิงค์เกอร์จะลิงก์ไฟล์อ็อบเจ็กต์โค้ดทั้งหมดของคุณ

โปรแกรมของคุณจะไม่ถูกเรียกใช้งานเว้นแต่จะอยู่ในหน่วยความจำหลัก


1
  • คอมไพเลอร์ : ซึ่งแปลงรูปแบบที่มนุษย์เข้าใจได้เป็นรูปแบบที่เครื่องเข้าใจได้
  • Linker : ซึ่งแปลงรูปแบบที่เครื่องเข้าใจเป็นรูปแบบที่เข้าใจได้ของระบบปฏิบัติการ
  • Loader : เป็นเอนทิตีที่โหลดและรันโปรแกรมลงใน RAM

Linker & Interpreter เป็นล่ามที่รับโค้ดทีละบรรทัดและดำเนินการทีละบรรทัด


1
  • คอมไพเลอร์: ตัวแปลภาษาที่แปลงโปรแกรมที่สมบูรณ์เป็นภาษาเครื่องเพื่อสร้างโปรแกรมที่คอมพิวเตอร์สามารถประมวลผลได้ทั้งหมด
  • Linker: โปรแกรมยูทิลิตี้ที่ใช้ไฟล์อ็อบเจ็กต์ที่คอมไพล์อย่างน้อยหนึ่งไฟล์และรวมเข้ากับไฟล์ปฏิบัติการหรืออ็อบเจ็กต์ไฟล์อื่น
  • Loader: โหลดรหัสปฏิบัติการลงในหน่วยความจำสร้างโปรแกรมและกองข้อมูลเริ่มต้นการลงทะเบียนและเริ่มการทำงานของรหัส

1

คอมไพเลอร์ จะแปลงซอร์สโค้ดเป็นอ็อบเจ็กต์โค้ด

Linker มันรวมไฟล์อ็อบเจ็กต์หลายไฟล์ไว้ในไฟล์โปรแกรมปฏิบัติการไฟล์เดียว

Loader มันโหลดไฟล์ปฏิบัติการลงในหน่วยความจำหลัก


1
ฉันคิดว่าคำตอบของคุณส่วนใหญ่ครอบคลุมอยู่ใน 14 คำตอบคุณภาพสูงที่มีอยู่ในช่วง 10 ปีที่ผ่านมา
Nicolas Gervais

0

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


0

คอมไพเลอร์แปลบรรทัดของโค้ดจากภาษาโปรแกรมเป็นภาษาเครื่อง

Linkerสร้างลิงค์ระหว่างสองโปรแกรม

Loaderโหลดโปรแกรมลงในหน่วยความจำในฐานข้อมูลหลักโปรแกรม ฯลฯ


-1

คอมไพเลอร์: เป็นซอฟต์แวร์ระบบที่แก้ไขข้อผิดพลาดของโปรแกรมไฟล์ออบเจ็กต์ข้อความ ฯลฯ

Linker: เป็นซอฟต์แวร์ระบบที่รวมไฟล์ออบเจ็กต์อย่างน้อยหนึ่งไฟล์และรหัสไลบรารีบางส่วนที่เป็นไปได้ในไลบรารีบางไลบรารี

Loader: โปรแกรมที่โหลดไฟล์ปฏิบัติการไปยังหน่วยความจำหลักของเครื่อง

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