본문 바로가기

코딩 이야기/컴파일러

컴파일러 공부하고 개발하기 #00 - 전처리, 컴파일, 어셈블, 링크

반응형

서론

 

일단 이 글은 필자가 아오키 미네로우 작가님의 '컴파일러 구조와 원리' 라는 책을 읽고 공부하며 진행한다. 주로 이 책의 진행의 포커스가 맞춰져있고, 그냥 이 책을 조금 요약하고 정리하고 거기에 나의 느낀점 등을 정리해서 쓴다고 보는 게 좋을 것이다.

이번 글에서는 여러 용어와 컴파일 과정에 대해 다룰 것이다.

 

 

 

컴파일러의 정의

 

컴파일러란 프로그래밍 언어의 소스 코드를 다른 형식으로 변환하는 소프트웨어를 뜻한다. 그리고 우린 이 작업을 컴파일이라고 부른다.

 

최근에 C언어를 공부한 사람이라면 여러 IDE를 통해 배웠을 것이다. 거기서 코드를 실행시키며 문법을 배울텐데 그 경우 빌드 버튼을 누르자마자 콘솔창이 실행되고 그 콘솔창에 자기가 만든 코드가 띄워질 것이다.(비주얼 스튜디오를 안쓴지 꽤 되서 햇갈린다.) 하지만 원래 C언어의 기본적인 컴파일러 GCC로 컴파일하게 되면 실행파일이라는 것이 생성된다. 즉 바로 콘솔로 뭐가 뜨거나 하진않는다. 이후 그 실행파일을 실행시킴으로써 콘솔이 나타나게 된다.

 

실행 파일이란?

 

리눅스에서의 실행 파일은 일반적으로 ELF의 형식을 갖고 있다. 우리가 사용하는 리눅스 명령어 ls, cp, pwd, mv 등 전부 ELF 파일 형태로 따로 존재하는 파일이다. ELF는 기계어로 이루어진 코드와 정보(메타 데이터)로 이루어져 있다.

 

컴파일 과정

  1. PreProcess(전처리)
  2. (좁은 의미의)Compile
  3. Assemble
  4. Link

 

PreProcess(전처리)란?

 

소스 코드의 헤더 파일을 처리한다. #include 나 #math.h 같은 헤더 파일 말이다. 헤더파일을 끌고 와서 매크로가 전개된다고 하는데, 여기서 '매크로'에 대해 알아본 결과, 컴파일러가 매크로를 만나면 해당 문자열로 변환한다? 라는 개념인 듯하다. 즉

#define Plus(a,b) a-b

int main(){
	int result;
	result = Plus(15,8);
    printf("%d", result);
}

라고 코드를 입력하면 컴파일러가 읽으면서 define으로 선언된 Plus()를 코드에서 맞닥트리게 되면 a-b 로 변환해주는 게 매크로의 개념이다. 헤더파일에는 수많은 매크로가 있고 전처리기는 이 헤더파일을 보고 모든 매크로를 전개시킨다. 간단히 말하자면 헤더파일의 내용을 복붙한다. 추가로 주석을 제거시킨다.

 

(좁은 의미의)Compile이란?

 

전처리가 완료된 소스코드를 어셈블리 언어로 변환한다.

 

(좀 더 깊게 알아보려 조사했으나 원래 그냥 단순히 이 개념이 맞다.)

 

Assemble(어셈블)이란?

 

어셈블리 언어가 된 소스 코드를 Assembler(어셈블러)를 통해 기계어로 변환시킨다. 어셈블러의 출력은 오브젝트 파일(확장자 .o)이다.

 

Link(링크)란?

 

어셈블러가 출력한 오브젝트 파일을 최종적으로 사용할 수 있게 변환하는 작업이 링크이다. 이 단계에서 라이브러리가 결합된다. 오브젝트 파일을 링크함으로서 .out 이라는 확장자를 가진 실행 파일이 생성된다.

 

 

 

 

끝맺는 말

 

필자가 4년전에 코딩을 처음 배울때 몰랐던 개념. 매크로의 정의 등 여러가지 몰랐던 개념들을 익히게 되서 좋았다. 코딩을 쉬기 전에 C++로 백준 풀다가 오랜만에 C언어를 쓰니, C언어의 주요 헤더파일 stdio.h 도 이름을 까먹어서 놀랐다.

 

 

잡담

 

정말 간만에 블로그 글을 쓰게 되었다. 일기 같은 것들은 전부 타사의 블로그에 기록하고 있다보니 글을 안쓴 것도 있고, 작년 2022년에 수능 준비한답시고 코딩을 너무 오랫동안 놓았어서 살짝 감이 안잡히긴하나 그래도 감도 잡을 겸 열심히 해보겠다.

 

반응형