3.3.1 Processes and Compilation Process
프로세스와 컴파일 과정
1. 프로세스
프로세스는 실행 중인 프로그램을 의미하며, 운영체제에서 가장 중요한 개념 중 하나입니다. 각 프로세스는 독립된 메모리 공간을 가지며, CPU에서 실행됩니다. 프로세스는 프로그램 코드, 데이터, 힙, 스택으로 구성됩니다. 프로그램이 실행될 때 운영체제는 새로운 프로세스를 생성하여, 이를 메모리에 로드하고 CPU에서 실행할 수 있도록 합니다.
2. 컴파일 과정
컴파일은 고급 프로그래밍 언어로 작성된 소스 코드를 기계어로 번역하여 실행 가능한 파일로 만드는 과정입니다. 컴파일러는 이 과정을 자동으로 수행하며, 여러 단계를 거쳐 소스 코드를 실행 파일로 변환합니다. 컴파일 과정은 다음과 같이 진행됩니다.
2.1 전처리기(Preprocessor)
전처리기는 소스 코드의 주석을 제거하고, 매크로를 확장하며, #include
지시문을 처리하여 헤더 파일을 포함시킵니다. 전처리기의 주요 작업은 코드 전처리로, 이는 컴파일러가 이해할 수 있는 형태로 소스 코드를 변환하는 것입니다.
주석 제거: 소스 코드에 포함된 주석을 제거합니다.
매크로 처리: 매크로 지시문을 확장하여 실제 코드로 대체합니다.
헤더 파일 포함:
#include
지시문에 따라 필요한 헤더 파일을 포함시킵니다.
2.2 컴파일러(Compiler)
컴파일러는 전처리된 소스 코드를 어셈블리어로 변환합니다. 컴파일러는 구문 분석, 의미 분석, 최적화 등의 단계를 거쳐 소스 코드를 분석하고, 효율적인 기계어 코드로 변환합니다. 컴파일러의 주요 작업은 코드 변환으로, 이는 어셈블러가 이해할 수 있는 형태로 소스 코드를 변환하는 것입니다.
구문 분석: 소스 코드의 문법을 검사합니다.
의미 분석: 변수와 함수의 의미를 검사합니다.
코드 최적화: 실행 속도를 높이기 위해 코드 최적화를 수행합니다.
2.3 어셈블러(Assembler)
어셈블러는 컴파일러가 생성한 어셈블리 코드를 목적 코드(object code)로 변환합니다. 목적 코드는 기계어로 작성된 코드로, 실행 파일의 일부가 됩니다. 어셈블러의 주요 작업은 코드 변환으로, 이는 목적 코드를 생성하여 링커가 처리할 수 있는 형태로 변환하는 것입니다.
목적 코드 생성: 어셈블리 코드를 기계어로 변환합니다.
파일 확장자: 각 운영체제마다 목적 코드의 확장자는 다릅니다. 예를 들어, 리눅스에서는
.o
, 윈도우에서는.obj
확장자를 사용합니다.
2.4 링커(Linker)
링커는 여러 목적 파일과 라이브러리를 결합하여 실행 파일을 생성합니다. 링커는 각 목적 파일의 코드와 데이터를 결합하고, 외부 참조를 해결하여 하나의 실행 파일로 만듭니다. 링커의 주요 작업은 파일 결합으로, 이는 실행 가능한 형태로 목적 파일과 라이브러리를 결합하는 것입니다.
정적 라이브러리: 정적 라이브러리는 프로그램 빌드 시 모든 코드를 실행 파일에 포함시키는 방식입니다. 정적 라이브러리는 메모리 사용량이 많지만, 외부 의존성이 낮아 독립적으로 실행할 수 있습니다.
동적 라이브러리: 동적 라이브러리는 프로그램 실행 시 필요한 라이브러리를 동적으로 로드하는 방식입니다. 동적 라이브러리는 메모리 사용량이 적지만, 외부 의존성이 높아 실행 환경에 라이브러리가 필요합니다.
컴파일 과정 예시
다음은 컴파일 과정의 예시를 단계별로 설명합니다.
소스 코드 파일(Source Code File):
소스 코드 파일에는 프로그램의 소스 코드가 포함되어 있습니다. 예를 들어,
main.c
파일이 있을 수 있습니다.
전처리기(Preprocessor):
전처리기는 소스 코드 파일을 입력으로 받아 주석을 제거하고, 매크로를 처리하며, 헤더 파일을 포함시킵니다. 전처리 결과는 전처리된 소스 코드 파일이 됩니다.
컴파일러(Compiler):
컴파일러는 전처리된 소스 코드 파일을 입력으로 받아 어셈블리어로 변환합니다. 이 과정에서 구문 분석, 의미 분석, 코드 최적화가 수행됩니다. 컴파일러 결과는 어셈블리 코드 파일이 됩니다.
어셈블러(Assembler):
어셈블러는 어셈블리 코드 파일을 입력으로 받아 목적 코드로 변환합니다. 목적 코드는 기계어로 작성된 코드로, 실행 파일의 일부가 됩니다. 어셈블러 결과는 목적 코드 파일이 됩니다.
링커(Linker):
링커는 여러 목적 코드 파일과 라이브러리를 결합하여 실행 파일을 생성합니다. 링커는 각 목적 파일의 코드와 데이터를 결합하고, 외부 참조를 해결하여 하나의 실행 파일로 만듭니다. 링커 결과는 실행 파일이 됩니다.
Last updated