컴파일 단계 (Compilation)
전처리된 소스 코드를 기계어로 변환하는 과정
- 각 소스 파일(
.cpp)은 개별적으로 컴파일됨 - 컴파일이 완료되면 각각의 오브젝트 파일(Object File)이 생성됨
오브젝트 파일 (Object File)
컴파일 단계가 완료되면 생성되는 파일
확장자 종류
.o.obj
운영체제와 컴파일러에 따라 확장자가 달라짐
운영체제별 확장자
| 운영체제 | 확장자 |
|---|---|
| Linux, macOS (UNIX 계열) | .o |
| Windows | .obj |
컴파일러별 확장자
| 컴파일러 | 확장자 |
|---|---|
| GCC (GNU Compiler Collection) | .o |
| MSVC (Microsoft Visual C++) | .obj |
기계어 변환 과정
C++(고급 언어)
↓
어셈블리어(저급 언어)
↓
기계어(네이티브 코드)
전처리된 소스 코드는 이러한 과정을 거쳐 CPU가 실행 가능한 기계어로 변환됨.
고급 프로그래밍 언어
사용자가 읽고 이해하기 쉬운 고수준 언어
예시:
- C++
- C#
- Java
특징:
- 사람이 이해하기 쉬움
- 하드웨어를 직접 다루지 않음
- 컴파일러 또는 인터프리터를 통해 번역됨
어셈블리어 (저급 프로그래밍 언어)
특정 CPU 아키텍처에 맞는 저수준 언어
특징:
- 기계어와 거의 1:1 대응
- CPU 명령어를 텍스트 형태로 표현
- 메모리 및 레지스터를 직접 제어 가능
- 하드웨어 제어에 가까움
예시:
MOV AX, 1
ADD AX, 2
기계어 (네이티브 코드)
CPU가 직접 실행 가능한 바이너리 코드
01010100 11101010
특징:
- 0과 1로 이루어짐
- CPU가 바로 실행 가능
- 사람이 읽기 어려움
심볼(Symbol) 생성 및 심볼 테이블(Symbol Table) 등록
컴파일이 완료된 오브젝트 파일은 심볼(Symbol)과 심볼 테이블(Symbol Table)을 가짐
심볼(Symbol)
함수나 변수의 이름을 식별하기 위한 정보
예시:
void Attack()
{
}
여기서 Attack 이라는 이름이 심볼이 됨
심볼 테이블(Symbol Table)
함수나 변수의 이름과 메모리 위치 정보를 저장하는 테이블
즉,
이름 → 주소
를 매핑하는 테이블
심볼 테이블이 필요한 이유
다른 파일에 있는 함수나 변수를 사용하려면 해당 위치를 알아야 하기 때문
예시:
// A.cpp
void Attack()
{
}
// B.cpp
extern void Attack();
Attack();
B.cpp는 Attack() 함수의 실제 위치를 모름
그래서 컴파일 단계에서:
Attack심볼 생성- 심볼 테이블에 등록
- 이후 링크 단계에서 실제 주소 연결
과정을 수행함
컴파일 단계에서 수행하는 심볼 작업
소스 파일 내부의:
- 함수
- 전역 변수
- 정적 변수
등에 대해 심볼 생성
예시:
int HP = 100;
void Move()
{
}
생성되는 심볼 예시:
HP
Move
링크 단계와의 관계
컴파일 단계에서는:
- 심볼 생성
- 심볼 테이블 등록
까지만 수행함
실제로:
함수와 변수의 실제 위치 연결
은 다음 단계인 링크(Link) 단계에서 처리됨
정리
| 개념 | 설명 |
|---|---|
| 컴파일 단계 | 전처리된 코드를 기계어로 변환 |
| 오브젝트 파일 | 컴파일 결과 생성되는 파일 |
.o |
Linux/macOS 계열 오브젝트 파일 |
.obj |
Windows 계열 오브젝트 파일 |
| 고급 언어 | 사람이 읽기 쉬운 언어 |
| 어셈블리어 | CPU 명령어를 텍스트로 표현 |
| 기계어 | CPU가 직접 실행하는 바이너리 코드 |
| 심볼 | 함수/변수 이름 식별 정보 |
| 심볼 테이블 | 이름과 주소 정보를 저장하는 테이블 |
핵심 요약
- 컴파일 단계는 코드를 기계어로 변환하는 과정
- 각
.cpp파일은 개별적으로 컴파일됨 - 결과로 오브젝트 파일(
.o,.obj) 생성 - 컴파일 과정에서 함수와 변수의 심볼 생성
- 생성된 심볼은 심볼 테이블에 등록됨
- 실제 주소 연결은 링크 단계에서 수행됨