링크 단계 (Linking)
링커(Linker)가 여러 개의 오브젝트 파일과 라이브러리를 연결하여 최종 실행 파일을 생성하는 과정
링크 단계에서 수행하는 작업
- 오브젝트 파일 병합
- 심볼 해석(Symbol Resolution)
- 주소 할당(Address Assignment)
- 재배치(Relocation)
오브젝트 파일 병합
컴파일/어셈블 단계에서 생성된 여러 오브젝트 파일들을 하나로 연결하는 과정
예시:
Player.obj
Enemy.obj
Game.obj
↓
Game.exe
심볼 해석 (Symbol Resolution)
현재 오브젝트 파일이 참조하는 함수나 변수가 실제 어디에 존재하는지 찾는 과정
예시:
extern void Attack();
Attack();
링커는 Attack 심볼이 어느 오브젝트 파일에 있는지 탐색함
주소 할당 (Address Assignment)
링크 단계에서 각 함수와 변수에 실제 메모리 주소를 결정하는 과정
컴파일/어셈블 단계에서는 아직 프로그램이 메모리 어디에 배치될지 모르기 때문에
실제 메모리 주소 대신 오프셋(섹션 내부 상대 위치)만 저장되어 있음
예시
.text 섹션
0byte : Move()
20byte : Attack()
50byte : Jump()
여기서 Attack()의 위치는:
.text 시작 기준 +20byte
라는 상대 위치 정보만 존재함
아직 실제 주소는 아님
링크 단계
링커(Linker)는 여러 오브젝트 파일을 병합한 뒤:
.text 섹션의 실제 시작 주소
를 결정함
예시:
.text 시작 주소 = 0x1000
실제 주소 계산
Attack()의 오프셋이:
20byte
라면
링커는:
0x1000 + 20
를 계산하여:
0x1014
같은 실제 메모리 주소를 결정함
주소 할당의 역할
즉 주소 할당은 오프셋을 기반으로 실제 메모리 주소를 계산하여 배정하는 작업
재배치 (Relocation)
주소 할당 이후, 코드 내부의 임시 주소나 상대 위치 정보를 실제 메모리 주소로 수정하는 과정
컴파일/어셈블 단계에서는 실제 메모리 주소를 알 수 없기 때문에 오프셋 또는 임시 참조 정보 형태로 저장되어 있음
예시
extern void Attack();
Attack();
현재 오브젝트 파일은 Attack()의 실제 주소를 모르기 때문에:
"나중에 실제 주소로 수정 필요"
라는 재배치 정보(Relocation Information)를 저장함
링크 단계
링커가 Attack()의 실제 주소를 결정했다고 가정:
Attack 실제 주소 = 0x1014
그러면:
Attack() 호출 위치의 임시 값
을
0x1014
로 수정함
이 작업이 재배치(Relocation)
재배치의 역할
재배치는 임시 주소/참조 정보 를 실제 메모리 주소로 교체하는 작업이다.
정적 링크 (Static Linking)
링커가 라이브러리 코드를 실행 파일 내부에 직접 포함시키는 방식
정적 라이브러리 확장자
| 운영체제 | 확장자 |
|---|---|
| Linux/macOS | .a |
| Windows | .lib |
장점
- 실행 시 별도 라이브러리 파일 필요 없음
- 실행 파일만 배포하면 됨
단점
- 실행 파일 크기 증가
- 라이브러리 수정 시 전체 재컴파일 필요
동적 링크 (Dynamic Linking)
실행 시 필요한 라이브러리를 OS가 로드하는 방식
링크 단계에서는:
"이 함수는 DLL/SO에서 가져올 예정"
이라는 참조 정보만 저장함
동적 라이브러리 확장자
| 운영체제 | 확장자 |
|---|---|
| Linux/macOS | .so |
| Windows | .dll |
장점
- 실행 파일 크기가 작음
- 여러 프로그램이 라이브러리 공유 가능
- 라이브러리만 교체 가능
단점
- 라이브러리 파일이 없으면 실행 불가
- 배포 시 라이브러리도 함께 제공해야 함
동적 라이브러리의 재배치
프로그램 실행 시:
- OS 로더가 DLL/SO 로드
- 실제 메모리 위치 결정
- 함수/변수 주소 연결
- 재배치 수행
즉:
동적 라이브러리는 실행 중에 주소 연결이 완료됨
전체 흐름
소스 코드
↓
전처리
↓
컴파일
↓
어셈블리
↓
오브젝트 파일 생성
↓
링크
↓
실행 파일 생성
↓
실행 시 동적 라이브러리 로드
핵심 요약
- 링크 단계는 여러 오브젝트 파일을 연결하는 과정
- 링커가 심볼을 찾아 실제 주소를 연결함
- 컴파일 단계의 상대 주소를 실제 주소로 변경함
- 정적 라이브러리는 실행 파일에 포함됨
- 동적 라이브러리는 실행 시 OS가 로드함
- 재배치는 임시 주소를 실제 주소로 수정하는 작업