# 컴파일

\


### 프로그램 실행 과정

열심히 개발한 프로그램을 실행시키기 위해서는 크게 **컴파일** - **링킹** - **로더** 의 과정을 거쳐야 한다. 해당 과정 각각을 한번 알아보도록 합시다!

\


## 컴파일

![image](https://github.com/jaepyo-Lee/lockmanager/assets/74135929/34986db7-43d2-4340-9822-49f16a8b033a)

컴퓨터가 이해하는 언어는 기계어입니다. 하지만 개발자들은 C, Java와 같은 프로그래밍 언어 즉, **고급언어**를 통해 개발하기 때문에 고급언어를 기계어로 바꿔주는 과정이 필요하고, 이것을 **컴파일**이라 합니다.

\


### 컴파일 과정

![image](https://github.com/jaepyo-Lee/lockmanager/assets/74135929/18926055-ae82-47b8-a633-cec8e7c79c17)

**4가지 과정**을 통해 컴파일됩니다. 컴파일 과정속에 링킹 과정을 넣기도 하지만 링킹은 따로 자세히 알아보도록 하겠습니다.

\


### ◻️ 전처리

전처리기를 통해 소스코드(.c)를 전처리한 소스코드(.i)로 변환하는 과정으로 정말 코드만을 남기는 과정입니다.

대표적으로 세가지 과정을 거칩니다.

1. 주석 제거
   * 프로그램 실행에 필요없는 모든 주석을 삭제합니다.
2. 라이브러리 삽입
   * 라이브러리의 내용을 소스코드로 복사합니다. 라이브러리의 함수원형은 링킹과정에서 실제 함수가 정의되어 있는 오브젝트 파일과 결합됩니다.
3. 매크로 치환 및 적용
   * \#define 지시문에 정의된 매크로를 저장하고 같은 문자열을 만나면 #define 된 내용으로 치환한다. 간단하게 말해 매크로 이름을 찾아서 정의한 값으로 전부 바꿔준다.

\


### ◻️ 컴파일

컴파일러를 통해 전처리된 소스코드(.i)를 어셈블리어 코드(.s)로 변환해주는 과정으로, 컴파일 과정의 핵심과정입니다.

\


### ◻️ 어셈블리

어셈블러를 통해 어셈블리어 코드(.s)를 오브젝트 파일(.o)로 변환해주는 과정이다.

\
\


## 링킹

컴파일된 소스 코드는 일반적으로 오브젝트 파일 형태로 만들어집니다. 하지만 오브젝트 파일 자체로는 프로그램을 실행시킬 수 없습니다. 이를 실행 가능한 형태로 변환하기 위해서는 링킹(linking)이라는 과정이 필요합니다.

오브젝트 파일은 실행 파일(exe 파일 등)로 변환되어야 프로그램을 실행할 수 있습니다. 링킹은 이러한 오브젝트 파일을 하나로 합치고, 필요한 라이브러리와 연결하여 실행 파일을 생성하는 과정입니다.

* 장점
  * 모든 라이브러리을 하나의 소스파일에 넣어 오브젝트파일로 만드는 것이 아닌 작은 모듈로 나눠 관리하는 것을 가능하게 만들어준다.

\


> 링킹의 종류(정적 링킹, 동적 링킹)

\


### 정적 링킹(**Static Linking**)

![image](https://github.com/jaepyo-Lee/lockmanager/assets/74135929/095e7a09-3c0a-49dc-a806-cec5f79575fd)

정적 링킹이란 **실행파일을 만들 때 사용하는 모든 라이브러리 모듈을 복사**하는 방식입니다. 즉, 자신이 작성한 프로그램에서 A라는 외부 라이브러리를 사용했다면, A라는 외부 라이브러리에 대한 정보를 자신이 작성한 프로그램의 실행파일을 만들 때 복사해오는 방식입니다.

\


* 장점
  1. 실행파일안에 라이브러리의 정보가 포함되어 있어 동적링킹에 비해 빠르다
  2. 불일치에 대한 걱정을 하지 않아도 된다.
     * 정적 링킹 프로그램에서 모든 코드는 하나의 실행 모듈에 담기기 때문이다.
* 단점
  1. 여러 개의 프로그램에서 같은 라이브러리를 사용하여도, 모든 실행파일에 같은 라이브러리의 정보가 담겨, 프로그램은 크기가 크고 메모리 효율이 좋지 않다.
  2. 외부 함수가 변경이 생길 경우 그 변화를 적용하기 위해서 다시 컴파일하여 다시 링킹을 해야 한다.
     1. 실행 가능한 목적파일을 만들 때 A에 관한 정보를 그냥 복사해왔기 때문에 외부 함수에 변화가 생겨도 다시 컴파일하지 않는 이상 적용이 안된다.

\


### 동적 링킹(**Dynamic Linking)**

![image](https://github.com/jaepyo-Lee/lockmanager/assets/74135929/549dfe31-9f30-4b1b-a9c2-61fcd98b10c4)

**동적 링킹이란 실행 가능한 목적 파일을 만들 때 프로그램에서 사용하는 모든 라이브러리 모듈을 복사하지 않고 해당 모듈의 주소만을 가지고 있다**가, 런타임에 실행 파일과 라이브러리가 메모리에 위치될 때 해당 모듈의 주소로 가서 필요한 것을 들고 오는 방식이다. 런타임에 운영체제에 의하여 이루어진다.

\


* 장점
  1. 정적 링킹 방식보다 실행 가능한 목적파일의 크기가 작아, 메모리와 디스크 공간을 아낄수 있다.
     * 여러 프로그램에서 외부 함수를 이용해도 외부 함수 정보는 하나만 있으면 된다.
     * 목적파일에서는 외부 함수를 복사하는 것이 아닌 외부 함수가 있는 곳의 주소만 가리키고 있으면 된다.
  2. 외부 함수의 변화가 생겨도 변화를 적용하기 위해 다시 컴파일해 다시 링킹할 필요가 없다.
     * 목적파일에 외부 함수에 관한 정보를 복사한 것이 아닌 외부 함수의 주소를 담았기 때문이다.
  3. 동적 라이브러리가 이미 존재하는 경우 로드되는 시간을 단축할 수 있다.
* 단점
  1. 매번 주소를 따라가야 하는 오버헤드가 존재해, 정적 링킹 방식보다 느리다.
  2. 불일치에 대한 문제를 고려해야 한다.
     * 사용하던 외부 함수가 시스템에서 제거가 된다면, 해당 프로그램의 실행 가능 목적파일에는 외부 함수의 주소가 있어서 존재하는 것처럼 동작을 해 제대로 실행될 수 없다.

> 오버헤드(overhead) : 어떤 처리를 하기 위해 들어가는 간접적인 처리 시간·메모리 등

\
\


## 로더

컴파일 과정에서 만들어진 실행파일(.exe)을 cpu에 의해 실행시키기 위해서 메모리에 파일의 내용을 적재해야합니다. 이러한 역할을 하는것을 **로더**라고 합니다. 로더는 기본적으로 다음과 같은 기능을 차례로 수행하지만, 로더의 각 기능을 언어 번역 프로그램 또는 링커 등의 시스템 소프트웨어가 수행할 수도 있다.

* **할당(Allocation)** : 실행 프로그램을 실행시키기 위해 기억장치 내에 옮겨놓을 공간을 확보하는 기능
* **연결(Linking)** : 부 프로그램 호출 시 그 부 프로그램이 할당된 기억장소의 시작주소를 호출한 부분에 등록하여 연결하는 기능
* **재배치(Relocation)** : 디스크 등의 보조기억장치에 저장된 프로그램이 사용하는 각 주소들을 할당된 기억장소의 실제 주소로 배치시키는 기능
* **적재(Loading)** : 실행 프로그램을 할당된 기억공간에 실제로 옮기는 기능

\


### 로더의 종류

**1) 컴파일 즉시 로더(Compile And Go)**

* 별도의 로더 없이 언어 번역 프로그램이 로더의 기능까지 수행하는 방식이다.
* 연결 기능은 수행하지 않고 할당, 재배치, 적재 작업을 모두 언어 번역 프로그램이 담당한다.

**2) 절대 로더(Absolute Loader)**

* 목적 프로그램을 기억장소에 적재시키는 기능만 수행하는 로더로, 로더 중 가장 간단한 프로그램으로 구성되어 있다.
* 기억장소 할당이나 연결을 프로그래머가 직접 지정하며 한번 지정한 주기억장소의 위치는 변경이 어렵다.

**3) 직접 연결 로더(Direct Linking Loader)**

* 일반적인 기능의 로더로, 로더의 기본 기능 네 가지를 모두 수행하는 로더이다.
* 재배치 로더(Relocation Loader), 상대 로더(Relative Loader)라고도 한다.

**4) 동적 적재 로더(Dynamic Loading Loader)**

* 프로그램을 한꺼번에 적재하는 것이 아니라 실행 시 필요한 부분만을 적재하고 나머지 부분은 보조기억장치에 저장해두는 것으로, 호출 시 적재(Load-On-Call)라고도 한다.
* 프로그램의 크기가 주기억장치의 크기보다 큰 경우에 유리한 방법이다.

\
\


## Ref

* https://seohs.tistory.com/259
* https://live-everyday.tistory.com/67
* https://live-everyday.tistory.com/69
* https://hbesthee.tistory.com/1410
* https://d2.naver.com/helloworld/1230
* https://steady-snail.tistory.com/67
* https://www.sktenterprise.com/bizInsight/blogDetail/dev/2434
