ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [배열] 컴파일링
    Stage/Computer Science 2021. 5. 27. 10:40

    학습목표

    컴파일링의 네 단계를 설명할 수 있다.

     

    1. 동작원리

    이전에 사용한 예제 코드를 다시 보면서 동작 원리를 이해해보자.

    1.1

    #include <stdio.h>
    
    int main(void)
    {
        printf("hello, world\n");
    }
    • main 함수를 만나서 프로그램을 시작한다.
    • printf 함수를 수행해야 하는데, 그러려면 stdio.h 라이브러리가 필요하다. stdio.h 라이브러리에 대해 좀 더 자세히 알아보자.
    • stdio.h는 헤더 파일이고 C언어로 작성되어 있으며 파일 확장자가 .h로 끝난다.
    • stdio.h 파일에는 printf 함수의 프로토타입이 있어서 Clang 컴파일러가 프로그램을 컴파일 할 때 printf가 무엇인지 알려준다.

    1.2

    • clang hello.c로 컴파일하고 그 결과 a.out 이라는 머신코드가 만들어지면 ./a.out 명령으로 프로그램을 실행한다.
    • a.out 파일은 컴퓨터가 이해할 수 있는 0과 1로 만들어졌기 때문에 프로그램이 실행 가능하다.

    1.3

    clang -o hello hello.c
    • 의미없어보이는 a.out 이라는 파일명 대신 다른 이름(hello)으로 컴파일 하고 싶을 때 사용하는 명령어이다.

    1.4

    clnag -o hello hello.c -lcs50
    • stdio.h 말고 CS50 라이브러리도 사용해봤었는데 CS50 라이브러리를 사용한 프로그램을 컴파일 할 때는
      clang에 또 다른 프로그램(-lcs50)이 필요했다.
    • clang에게 CS50 라이브러리에 있는 모든 0과 1을 여기에 연결하라는 의미이다.
    • 조금 번거로운 이 과정들을 좀 간단히 하기 위해 우리는 make 프로그램을 이용하여 모든 컴파일 과정을 자동으로 처리했다.

     

    2. 컴파일링의 네 단계

    make나 clang을 사용해서 프로그램을 실행하면 네 단계를 거치게 된다.
    이 과정에서 어떤 일이 일어나는지 알아보자.



    1. 전처리(Precompile)

    • 전처리기에 의해 수행된다.
    • # 으로 시작되는 C 소스 코드는 전처리기에게 실질적인 컴파일이 이루어지기 전에 무언가를 실행하라고 알려준다.
    • 예를 들어, #include는 전처리기에게 다른 파일의 내용을 포함시키라고 알려준다.
      프로그램의 소스코드에 #include와 같은 줄을 포함하면, 전처리기는 새로운 파일을 생성하는데 이 파일은 여전히 C 소스 코드 형태이며, stdio.h 파일의 내용이 #include 부분에 포함된다.

    2. 컴파일(Compile)

    • 전처리기가 전처리한 소스 코드를 생성하고 나면 그 다음 단계는 컴파일이다.
    • 컴파일러라고 불리는 프로그램은 C 코드를 어셈블리어라는 저수준 프로그래밍 언어로 컴파일 한다.
    • 어셈블리는 C보다 연산의 종류가 훨씬 적지만, 여러 연산들이 함께 사용되면 C에서 할 수 있는 모든 것들을 수행할 수 있다.
    • C 코드를 어셈블리 코드로 변환시켜줌으로써 컴파일러는 컴퓨터가 이해할 수 있는 언어와 최대한 가까운 프로그램으로 만들어준다.
    • 컴파일이라는 용어는 소스 코드에서 오브젝트 코드로 변환하는 전체 과정을 통틀어 일컫기도 하지만, 구체적으로 전처리한 소스 코드를 어셈블리 코드로 변환시키는 단계를 말하기도 한다.

    3. 어셈블(Assemble)

    • 소스 코드가 어셈블리 코드로 변환되면, 다음 단계는 어셈블 단계로 어셈블리 코드를 오브젝트 코드로 변환시키는 것이다.
    • 컴퓨터의 중앙처리장치(CPU)가 프로그램을 어떻게 수행해야 하는지 알 수 있는 명령어 형태인 0과 1들로 바꿔주는 작업을 말한다.
    • 이 변환작업은 어셈블러라는 프로그램이 수행한다.
    • 소스 코드에서 오브젝트 코드로 컴파일 되어야 할 파일이 딱 한 개라면, 컴파일 작업은 여기서 끝이난다.
      그러나 그렇지 않은 경우에는 링크라 불리는 단계가 추가된다.

    4. 링크(Link)

    • 만약 프로그램이 (math.h나 cs50.h와 같은 라이브러리를 포함해) 여러 개의 파일로 이루어져 있어 하나의 오브젝트 파일로 합쳐져야 한다면 링크라는 컴파일의 마지막 단계가 필요하다.
    • 링커는 여러 개의 다른 오브젝트 코드 파일을 실행 가능한 하나의 오브젝트 코드 파일로 합쳐준다.
    • 예를 들어, 컴파일을 하는 동안에 CS50 라이브러리를 링크하면 오브젝트 코드는 GetInt()나 GetString() 같은 함수를 어떻게 실행할 지 알 수 있게 된다.
    • 이 네 단계를 거치면 최종적으로 실행 가능한 파일이 완성된다.

    'Stage > Computer Science' 카테고리의 다른 글

    [배열] 배열  (0) 2021.05.27
    [배열] 디버깅  (0) 2021.05.27
    [C언어] 하드웨어의 한계  (0) 2021.05.27
    [C언어] 사용자 정의 함수, 중첩 루프  (0) 2021.05.27
    [C언어] 자료형, 형식 지정자, 연산자  (0) 2021.05.27

    댓글