지금까지 작성했던 C 코드를 복습해보자.
main
이라는 함수가 있다. 프로그램의 시작점으로서 실행 버튼을 클릭하는 것과 같다.
printf
는 출력을 담당하는 함수다. printf
함수를 사용하기 위해서는 stdio.h
라이브러리가 필요하다.
정확하게는 stdio.h
는 헤더 파일로 C 언어로 작성되어 있고 파일명이 .h
로 끝나는게 헤더 파일이다.
이 파일에는 printf
함수의 프로토타입이 있어서 Clang 컴파일러가 프로그램을 컴파일할 때 printf
가 무엇인지 알려주는 역할을 한다.
#include <stdio.h>
int main(void)
{
printf("Hello, world!\\n");
}
코드를 clang hello.c
로 컴파일하고 ./a.out
명령으로 프로그램을 실행할 때 컴퓨터가 이해하는 0과 1로 가득 찬 파일 a.out
을 생성해 실행 가능하게 한다.
만약 a.out
과 다른 이름(hello)으로 컴파일하고 싶다면 아래와 같이 명령행 인자를 추가해야 한다.
clang -o hello hello.c
우리는 CS50 라이브러리를 사용했기 때문에 컴파일할 때는 clang
에 또 하나의 옵션 -lcs50
이 필요했다.
그래야 clang
이 실행된다.
clang -o hello hello.c -lcs50
clang
에게 CS50 라이브러리에 있는 모든 0과 1들을 연결하라는 의미다.
더 간단하게는 이전에 배웠듯이 make
프로그램을 이용하면 이 모든 컴파일 과정을 자동으로 처리할 수 있다.
make
나 clang
을 사용해서 프로그램을 실행할 때는 아래 네 단계를 거친다.
- 전처리(Preprocessing)
- 컴파일(Compiling)
- 어셈블링(Assembling)
- 링킹(Linking)
우리가 명령어를 실행할 때 정확히 어떤 일이 일어나는지 알아보자.
전처리$_{Preprocessing}$
컴파일의 첫 번째 단계는 전처리이다.
전처리기는 C언어에서 #
으로 시작되는 코드로 컴파일이 이루어지기 전에 처리한다.
#include
는 전처리기에게 다른 파일의 내용을 포함시키라고 지시한다.
프로그램의 소스 코드에 #include
와 같은 줄을 포함하면 전처리기는 새로운 파일을 생성하는데 이 파일은 여전히 C 소스 코드 형태고 stdio.h
파일의 내용이 #include
부분에 포함된다.
컴파일$_{Compiling}$
전처리기가 전처리한 소스 코드를 생성하고 나면 다음 단계는 컴파일이다.
컴파일러는 C 코드를 어셈블리어라는 저수준 프로그래밍 언어로 변환한다.
어셈블리는 C보다 연산의 종류가 훨씬 적지만 여러 연산들이 함께 사용되면 C에서 할 수 있는 모든 것을 수행할 수 있다.
컴파일러는 C 코드를 어셈블리 코드로 변환해 컴퓨터가 이해할 수 있는 언어와 최대한 가까운 프로그램으로 만들어준다.
컴파일이라는 용어는 소스 코드에서 오브젝트 코드로 변환하는 전체 과정을 의미하기도 하지만, 구체적으로는 전처리한 소스 코드를 어셈블리 코드로 변환시키는 단계를 말하기도 한다.
어셈블$_{Assembling}$
소스 코드가 어셈블리 코드로 변환되면 다음 단계는 어셈블리 코드를 오브젝트 코드로 변환시키는 어셈블 단계이다.
컴퓨터의 중앙처리장치가 프로그램을 어떻게 수행해야 하는지 알 수 있는 명령어 형태의 연속된 0과 1들로 바꿔주는 작업을 수행한다. 이 변환 작업은 어셈블러라는 프로그램이 수행한다.
만약 소스 코드에서 오브젝트 코드로 컴파일되어야 할 파일이 하나뿐이라면 컴파일 작업은 여기서 끝난다.
그러나 여러 파일로 구성된 프로그램의 경우에는 마지막 단계인 링크가 필요하다.
링크$_{Linking}$
프로그램이 여러 파일로 이루어져 있다면 링커가 여러 개의 오브젝트 코드 파일을 하나의 실행 가능한 오브젝트 코드 파일로 합쳐준다.
컴파일 동안에 CS50 라이브러리를 링크하면 오브젝트 코드는 get_int()
나 get_string()
같은 함수를 어떻게 실행할지 알 수 있게 된다.
이 네 단계를 거치면 최종적으로 실행 가능한 파일이 완성된다.
References
'CSE > CS 기초' 카테고리의 다른 글
[CS50] 배열 - 배열(1) (0) | 2024.06.13 |
---|---|
[CS50] 배열 - 디버깅 (0) | 2024.06.13 |
[CS50] C언어 - 하드웨어의 한계 (0) | 2024.06.12 |
[CS50] C언어 - 사용자 정의 함수, 중첩 루프 (0) | 2024.06.12 |
[CS50] C언어 - 자료형, 형식 지정자, 연산자 (1) | 2024.06.12 |
컴퓨터 전공 관련, 프론트엔드 개발 지식들을 공유합니다. React, Javascript를 다룰 줄 알며 요즘에는 Typescript에도 관심이 생겨 공부하고 있습니다. 서로 소통하면서 프로젝트 하는 것을 즐기며 많은 대외활동으로 개발 능력과 소프트 스킬을 다듬어나가고 있습니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!