program은 원래 이진 실행 파일 형태로 디스크에 저장되어 있다. 실행하려면 program을 memory로 가져와서 process context 내에 배치해야 한다. 이 시점에 가용한 CPU에서 실행할 수 있게 된다.
먼저 배치되는 과정부터 알아야 한다.
링커와 로더 (Linkers and Loaders)
일반적으로 program은 디스크에 이진 실행 파일(a.out 또는 prog.exe)로 존재한다. CPU에서 실행하려면 program을 memory로 가져와 process 형태로 배치되어야 한다.
먼저 소스 파일은 임의의 물리 memory 위치에 적재되도록 설계된 오브젝트 파일로 컴파일 된다.
object file: 컴파일러가 생성한 중간 단계 파일. 실행 파일이나 라이브러리는 이 오브젝트 파일을 링크해서 만든다.
relocatable file(재배치 가능한 파일): 실행가능한 파일이나 공유 오프젝트 파일을 생성하기 위해 다른 오브젝트 파일들과 링킹(linking)할 수 있는 코드와 데이터를 갖는다. 아직 실행 가능한 상태는 아니고 다른 오브젝트 파일들과 link가 가능하기 때문에 재배치를 할 수 있는 파일을 말한다.
shared object file(공유 오브젝트 파일): 두 context들을 링크할 수 있는 코드와 데이터를 갖는다.
- link editor는 또 다른 오브젝트 파일을 생성하기 위해 다른 재배치 가능한 파일과 공유 오브젝트 파일로 processing할 수 있다.
- 동적 링커는 process 이미지를 생성하기 위해 실행가능한 파일과 다른 공유된 오브젝트를 결합한다.
- process 이미지(=context): processor의 실행환경이다. 프로그램 명령(text), data, stack, register 값, 시스템 데이터를 포함한다.
이러한 형식을 재배치 가능 오브젝트 파일이라고 한다. 다음으로 링커는 이러한 재배치 가능 오브젝트 파일을 하나의 이진 실행 파일로 결합한다. 링킹 단계에서 표전 C 또는 수학 라이브러리(플래그 -lm으로 지정)와 같은 다른 오브젝트 파일 또는 라이브러리도 포함될 수 있다.
로더는 이진 실행 파일을 memory에 적재하는 데 사용되며, CPU 코어에서 실행할 수 있는 상태가 된다. 링크 및 로드와 관련된 활동은 재배치로, program 부분에 최종 address를 할당하고 program 코드와 data를 해당 address와 일치하도록 조정하여 profram이 실행될 때 코드가 라이브러리 함수를 호출하고 변수에 접근할 수 있게 한다.

주소의 할당(Address Binding)
data = 101;
예를 들어 이러한 코드는 memory의 어떤 address에 101이란 값을 쓰는 program이다. 원시 program에서 주소는 숫자가 아닌 심볼 형태로(변수 count와 같이) 표현된다. 컴파일러가 이 심볼 주소를 재배치 가능 주소(예를 들어 "이 모듈의 첫 번째 바이트로부터 열네 번째 바이트 주소")로 binding시키고, 다음에 linker나 loader가 재배치 가능 주소를 절대 주소로 binding시킨다.
이 memory address를 언제 어떻게 결정하는가를 address binding이라고 하며 각 binding 과정은 한 address 공간에서 다른 address 공간으로 mapping하는 것이다.
memory address 공간에서 명령어와 데이터 binding은 그 binding이 이루어지는 시점에 따라 다음과 같이 구분된다.
- 컴파일 시간(compile time) 바인딩: 만일 process가 memory 내에 들어갈 위치를 compile 시간에 미리 알 수 있으면 compiler는 절대 코드(absolute code: 코드가 이미 정해진 memory address로 load되는 것을 말한다)를 생성할 수 있다. 예를 들면 사용자 process가 R번지로부터 시작한다는 것을 미리 알 수 있으면 compiler는 번역할 코드를 그 위치에서 시작해 나간다. 그러나 만일 이 위치가 변경되어야 한다면 이 코드는 다시 컴파일되어야 한다.
- 적재 시간(load time) 바인딩: 만일 process가 memory 내 어디로 올라오게 될지를 compile 시점에 알지 못하면 compiler는 일단 이진 코드를 재배치 가능 코드로 만들어야 한다. 이 경우에 심볼과 진짜 번지수와의 binding은 program이 main memory로 실제로 적재되는 시간에 이루어지게 된다. 이렇게 만들어진 재배치 가능 코드는 시작 address가 변경되면 아무 때나 사용자 코드를 다시 적재하기만 하면 된다.
- 실행 시간(execution time) 바인딩: 만약 process가 실행하는 중간에 memory 내의 한 segment로부터 다른 segment로 옮겨질 수 있다면 binding이 실행 시간까지 허용되었다고 말한다.
computer system에서 여러 가지 binding을 어떻게 효과적으로 구현할 수 있는가는 매우 중요한 점이다.
References
Operating System Concepts 10th edition
'운영체제' 카테고리의 다른 글
| Process(프로세스) (0) | 2022.07.15 |
|---|---|
| 컴파일(Compile) (0) | 2022.07.14 |
| 컴퓨터의 구성 (0) | 2022.07.08 |
| 운영체제 (0) | 2022.07.08 |