본문 바로가기

카테고리 없음

C언어 컴파일 과정/C 컴파일 과정 - 사좋배 공유

안녕하세요 제가 IT면접을 보면서 금융권은 C를 주로 사용하기 때문에 C에대한 질문을 할때가 꽤 많습니다.

질문은 내용은 거의 기본적인 컴파일 과정을 묻는 질문도 많습니다. 그래서 C 컴파일 과정을 설명하겠습니다.

 

일단 C언어는 Native언어입니다. 자바랑 많이 다릅니다.

 

 

위 그림처럼 작성한 코드는 다양한 과정을 거쳐 실행 가능한 바이너리 파일로 만들어집니다. 이렇게 만들어진 실행파일을 실행하면 바이너리 파일의 내용들이 주기억장치(RAM)로 적재(Load)되어 시스템에서 동작하게 됩니다.

 

1.전처리 과정

전처리 과정은 크게 두부분으로 나눌 수 있습니다.

1). 헤더 파일 삽입

2). 매크로 치환 및 적용

C소스 내에 헤더파일을 include 하는 것은 C언어의 문법적 특성과 관련된 것으로, C 언어에서는 함수를 사용하기전에 함수의 원형을 먼저 선언을 해야합니다.

따라서 어떠한 함수를 사용하려면 해당 함수가 정의되어 있는 헤더파일을 include 해야합니다. 

전처리기는 #include 구문을 만나면 해당하는 헤더파일을 찾아 그 파일의 내용을 순차적으로 삽입힙니다.

헤더파일을 다 삽입하면 이제 매크로 치환 작업이 들어갑니다. #define 된 부분을 심볼 테이블에 저장되고, 심볼 테이블에 들어있는 문자열과 같은 문자열을 만나면 #define 된 내용으로 치환합니다. 이때 #ifdef와 같은 다른 전처리기 매ㅡ로들도 같이 처리 됩니다.

 

2.컴파일 과정

전처리 과정이 끝나면 이제 컴파일 과정으로 들어갑니다. 

컴파일 과정은 크게 전단부, 중단부, 후단부로 나눌수 있습ㄴ다. 전처리가 긑난 .i 파일을 컴파일 하면 .s 어셈블리 코드로 이루어진 파일이 만들어 집니다.

 

1) 전단부(Front-end)

전단부에서는 언어 종속적인 부분을 처리합니다. 따라서 이 단계에서는 C언어로 작성된 코드와 C++, java등의 다른 언어로 작성된 코드들이 각각 다른 모듈에 의해 처리됩니다.

 

2) 중단부(Middle-end)

중단부에서는 전단부에서 넘겨받은 GIMPLE 트리를 SSA형태로 변환한후 아키텍쳐 비종속적인 최적화를 수행한수 최종적으로 후단부에 사용하는 RTL을 생성합ㄴ다.

 

3)후단부(Back-end)

아키텍쳐 종속적인 최적화는 각 프로그램 내의 명령어 중 아키텍처별로 좀 더 효율적인 명령어로 대체해 성능을 높이는 작업과 같이 아키텍쳐 특성에 따라 최적화를 수행하는 것을 말합니다.

이렇게 최적화를 마치면 어셈블리어로 구성된 .s 파일이 만들어 지게 됩니다.

 

3. 어셈블 과정

컴파일이 끝난 어셈블리 코드는 어셈블러에 의해 기계어로 어셈블됩니다.

어셈블러에 의해 생성되는 목적코드 파일은 어셈블된 프로그램의 명령어와 데이터가 들어있는 ELF 바이너리 포맷 구조를 갖습니다.

다음 단계인 링킹에서 링커가 여러개의 바이너리 파일을 하나의 실행파일로 묶기 위해서 각 바이너리의 정보를 효과적으로 파악하기 위해서 일정한 규칙을 갖게 형식화 해놓은 것입니다.

 

4.링킹 과정

어셈블리에 의해 ELF 포맷의 목적코드 파일들이 만들어지면 이제 링커가 나설 차례입니다.

링커는 오브젝트 파일들과 여러분의 프로그램에서 사용된 표준 C 라이브러리, 사용자 라이브러리들을 링크(Link)를 합니다.

printf()함수나 scanf()등의 표준 C라이브러리 함수들은 여러분이 직접 구현하지 않아도 미리 컴파일 되어있기 때문에 링크하는 과정만 거치면 사용할 수 있습니다. (표준 C 라이브러리는 별도로 명시하지 않아도 자동으로 링크됩니다.)

이렇게 링킹 과정이 끝나면 드디어 실행 가능한 실행파일이 만들어지게 됩니다.