[compiler-construction] 컴파일러, 링커, 로더는 무엇입니까?

컴파일러, 링커 및 로더의 의미와 작동 방식을 깊이 알고 싶었습니다. 모든 언어와 관련하여 바람직하게는 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 전 처리기 :-

C 전처리는 컴파일의 첫 번째 단계입니다. 다음을 처리합니다.

  1. #define 진술.
  2. #include 진술.
  3. 조건문.
  4. 매크로

유닛의 목적은 C 소스 파일을 Pure C 코드 파일로 변환하는 것입니다.

C 컴파일 :

단위에는 6 개의 단계가 있습니다 :

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) 사전 최적화 :

이 장치는 CPU와 독립적입니다. 즉, 두 가지 유형의 최적화가 있습니다.

  1. 사전 최적화 (CPU 독립적)
  2. 최적화 후 (CPU에 따라 다름)

이 단위는 다음 형식으로 코드를 최적화합니다.

  • I) 데드 코드 제거
  • II) 하위 코드 제거
  • III) 루프 최적화

I) 데드 코드 제거 :

예 :

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

여기서 컴파일러는 컴파일 타임에 ‘a’의 값을 알고 있으므로 if 조건이 항상 참인 것도 알고 있습니다. 따라서 코드에서 else 부분을 제거합니다.

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>
            -----
            -----

컨트롤이 바로 이동합니다.

마지막 단계는 연결 (실행 파일 또는 라이브러리 생성)입니다. 실행 파일이 실행되면 필요한 라이브러리가로드됩니다.


답변

  • 컴파일러는 코드를 읽고 분석하여 개체 파일이나 오류 메시지 목록으로 변환합니다.
  • 링커는 하나 이상의 개체 파일과 가능한 일부 라이브러리 코드를 일부 실행 파일, 일부 라이브러리 또는 오류 메시지 목록으로 결합합니다.
  • 로더는 실행 코드를 메모리로 읽고 주소 변환을 수행하고 프로그램 실행을 시도하여 실행중인 프로그램이나 오류 메시지 (또는 둘 다)를 발생시킵니다.

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)

소스-> 인터넷

코드 조각을 만들고 파일 (소스 코드)을 저장 한 다음

전처리 :-이름에서 알 수 있듯이 컴파일의 일부가 아닙니다. 실제 컴파일 전에 필요한 사전 처리를 수행하도록 컴파일러에 지시합니다. 이 단계를 텍스트 대체라고 부르거나 #으로 표시된 특수 전 처리기 지시문을 해석 할 수 있습니다.

컴파일 :-컴파일은 한 언어로 작성된 프로그램이 다른 대상 언어로 번역되는 과정입니다. 오류가있는 경우 컴파일러는 오류를 감지하고보고합니다.

조립 :-조립 코드는 기계 코드로 변환됩니다. 어셈블러를 특수 유형의 컴파일러라고 부를 수 있습니다.

연결 :-이 코드 조각에 다른 소스 파일을 연결해야하는 경우 링커를 연결하여 실행 파일로 만듭니다.

그 후에 일어나는 많은 과정이 있습니다. 예, 바로 여기에 로더의 역할이 있다고 짐작하셨습니다.

짐을 싣는 사람 :-실행 코드를 메모리에로드합니다. 프로그램 및 데이터 스택이 생성되고 레지스터가 초기화됩니다.

약간의 추가 정보 :-http: //www.geeksforgeeks.org/memory-layout-of-c-program/ , 저기 메모리 레이아웃을 볼 수 있습니다.


답변

컴파일러 : 고급 언어 프로그램을 기계 언어 프로그램으로 변환하는 프로그램입니다. 컴파일러는 어셈블러보다 지능적입니다. 모든 종류의 제한, 범위, 오류 등을 확인합니다. 그러나 프로그램 실행 시간이 더 길고 메모리의 더 많은 부분을 차지합니다. 속도가 느립니다. 컴파일러는 전체 프로그램을 거쳐 전체 프로그램을 기계 코드로 변환하기 때문입니다. 컴파일러가 컴퓨터에서 실행되고 동일한 컴퓨터에 대한 기계 코드를 생성하는 경우 자체 컴파일러 또는 상주 컴파일러라고합니다. 반면에 컴파일러가 컴퓨터에서 실행되고 다른 컴퓨터에 대한 기계어 코드를 생성하는 경우 크로스 컴파일러라고합니다.

링커 : 고급 언어에서는 일부 내장 헤더 파일 또는 라이브러리가 저장됩니다. 이러한 라이브러리는 미리 정의되어 있으며 프로그램 실행에 필수적인 기본 기능을 포함합니다. 이러한 함수는 링커라는 프로그램에 의해 라이브러리에 연결됩니다. 링커가 함수 라이브러리를 찾지 못하면 컴파일러에 알리고 컴파일러에서 오류를 생성합니다. 컴파일러는 프로그램 컴파일의 마지막 단계로 링커를 자동으로 호출합니다. 라이브러리에 내장되어 있지 않으며 사용자 정의 함수를 사용자 정의 라이브러리에 연결합니다. 일반적으로 긴 프로그램은 모듈이라고하는 더 작은 하위 프로그램으로 나뉩니다. 그리고 이러한 모듈은 프로그램을 실행하기 위해 결합되어야합니다. 모듈 결합 프로세스는 링커에 의해 수행됩니다.

로더 : 로더는 프로그램의 기계 코드를 시스템 메모리로로드하는 프로그램입니다. 컴퓨팅에서 로더는 프로그램로드를 담당하는 운영 체제의 일부입니다. 프로그램을 시작하는 과정에서 필수적인 단계 중 하나입니다. 프로그램을 메모리에 저장하고 실행할 준비를하기 때문입니다. 프로그램로드에는 실행 파일의 내용을 메모리로 읽어들이는 작업이 포함됩니다. 로드가 완료되면 운영 체제는로드 된 프로그램 코드에 제어를 전달하여 프로그램을 시작합니다. 프로그램 로딩을 지원하는 모든 운영 체제에는 로더가 있습니다. 많은 운영 체제에서 로더는 메모리에 영구적으로 상주합니다.


답변

Wikipedia는 좋은 대답을 가져야합니다. 여기 내 생각이 있습니다.

  • 컴파일러 : something.c 소스를 읽고 something.o 객체를 작성합니다.
  • 링커 : 여러 * .o 파일을 실행 가능한 프로그램으로 결합합니다.
  • 로더 : 실행 파일을 메모리에로드하고 실행을 시작하는 코드입니다.

답변

*

다른 모든 컴퓨팅 시스템에 대한 기본 개념이지만 Linux / unix 기반 시스템과 관련하여 설명됩니다.

*

링커 및 로더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

프로그램이 메모리에로드되면 PC (프로그램 카운터)가 첫 번째 명령을 가리 키도록하여이 프로그램으로 제어가 전송됩니다. a.out


답변

컴파일러:

.c 또는 .cpp 등의 유형일 수있는 소스 파일을 읽고이를 오브젝트 파일로 불리는 .o 파일로 변환합니다.

링커 :

여러 소스 파일에 대해 생성 될 수있는 여러 .o 파일을 실행 파일 (GCC의 ELF 형식)로 결합합니다. 두 가지 유형의 연결이 있습니다.

  • 정적 연결
  • 동적 연결

짐을 싣는 사람:

기계의 기본 메모리에 실행 파일을로드하는 프로그램입니다.


Linux에서이 세 단계의 프로그램 실행에 대한 자세한 연구는이를 읽어보십시오 .