본문 바로가기
C언어/C언어

[C언어]컴파일(Compilation) 단계

by Oliver_Candy 2023. 2. 16.

 


 

 

 

전처리 단계에 이어서 컴파일 단계에 대해서 알아보자.

컴파일은 컴파일러가 담당을 하고 확장된 소스코드 하나를 입력받아서 어셈블리어로 출력을 하게 된다.

 

 어셈블리어란?

어셈블리어는 기계어와 1:1로 대응하는 언어로 하드웨어에 가깝다. 출력되는 파일이 아직까지도 텍스트 파일이기 때문에 사람들이 읽을 수 있다. 기계는 아직까지도 읽지 못한다. 어셈블리어는 바이러니(이진) 코드가 아니기 때문이다. 

그리고 어셈블리코드는 정의를 모르는 심볼을 사용할 수 있다. 심볼의 예를 들면 함수나 변수의 이름을 뜻한다. 그래서 이전에 배운 헤더파일을 통한 선언 만으로 컴파일이 가능하게 된다!!

컴파일러가 심볼의 선언만 보고 판단하는 과정을 설명하겠다.

  1. 함수나 변수가 선언이 되어 있네? 근데 정의를 찾지 못하겠다.
  2. 일단 프로그래머가 선언을 해놨으니 정의는 어딘가에 있겠지? 선언만 믿고 일단 컴파일해 줄게
  3. (컴파일을 하다가 함수 사용하는 코드를 만났을 때) 아까 선언했던 함수, 변수네? 이 부분은 나중에 실체가 들어가야 돼
  4. 일단은 내가 여기에 구멍을 남겨둘게 누군가가 이 구멍을 메꿔주겠지?

 

 

이렇게 위와 같은 방식으로 컴파일러는 심볼의 선언만을 보고 컴파일을 해주기 때문에 그 파일에 정의가 없더라도 일단은 컴파일은 해준다. 여기서 구멍을 메꿔주는 누군가는 링크 단계에서 링커가 해준다.

 


 어셈블리어를 보는 방법

어셈블리어를 보는 방법은 cmd에서 컴파일 플레그 "-S"쓰면 알아서 .s파일로 저장이 된다.

clang -std=c89 -W -Wall -pedantic-errors -s main.c

이렇게 작성을 하게 되면 main.s파일이 생기게 된다.

아까 전에 말했던 구멍을 실제로 어셈블리어로 보자

main.s 파일

 

 

 

위 그림의 어셈블리어를 보면 call _add라고 되어있다. 이것이 _add()함수가 들어갈 거야 라는 구멍을 남겨 놓은 것이다. 진짜로 어셈블리어는 add함수 쪽에 구멍을 남긴다는 것을 알 수 있다.

그리고 add() 함수가 들어있는 adder.c 파일의 어셈블리어 코드 adder.s파일을 한 번 살펴보자

adder.s 파일

add()함수가 들어있는 adder.s 어셈블리어에서 젤 위에 _add라고 레이블이 되어있다. 나중에 링크 단계에서 이런 구멍들을 다 메꿔준다고 보면 된다.

 

 

 

 어셈블리어가 나왔다는 것의 의미는 무엇일까?

어셈블리어 코드는 이제 특정 플랫폼(mac, 리눅스, 윈도우, 32비트 ver, 64비트 ver)에서만 작동하는 코드로 바뀌었다는 뜻이다. C언어는 원래 크로스 플랫폼으로 어느 플랫폼에서도 같은 코드를 짜면 똑같이 실행이 되지만 여기서부터는 플랫폼마다 코드가 달라진다. 그래서 C언어 같은 고수준언어를 만든 이유도 플랫폼마다 코딩하기 싫어서 만들어졌다고 보면 된다.

그리고 어셈블리어에서는 이미 자료형의 크기가 결정되었다. 위에 어셈블리어를 보면 int, long, float같은 자료형이 보이지 않는다. 이미 특정 플랫폼에 맞게 자료형의 크기가 결정되어 메모리를 할당하는 코드가 만들어졌다.

 

 

2023.02.15 - [POCU/COMP2200(C언어)] - [C]C프로그램 빌드 과정(컴파일,링크,빌드의 차이)

 

[C언어]C프로그램 빌드 과정(컴파일,링크,빌드의 차이)

빌드(build)란? 빌드의 뜻은 소스코드를 기계가 이해할 수 있는 기계어로 변환해 주는 과정으로 명령어를 모두 모아서 실행 가능한 실행파일로 만드는 과정으로 세부적으로 나누면 4가지로 나뉘

olivertree-cs.tistory.com

 

 

출처 : POCU Academy COMP2200

 

댓글