목차
- 🤔 Address binding이란?
- 🧡 Compile time binding
- 💛 Load time binding
- 💚 Execution time binding
🤔 Address binding이란?
우리가 프로그램을 실행시키면 프로세스가 되어 Main Memory라고 불리는 RAM에 올라갑니다.
이때 메모리 주소는 우리가 프로그래밍을 할 때 사용하던 주소 그대로일 수도 있고, 그렇지 않을 수도 있습니다.
그 이유는 CPU가 만들어내는 가상의 주소인 Logical address(논리 주소)와 실제 메모리 상의 특정 번지를 나타내는 Physical address(물리 주소)를 어떻게 관련지을 것인지에 대한 다양한 방법이 있기 때문입니다.
즉, 프로세스를 메모리에 할당시킬 때, 물리 주소를 언제(When), 어떻게(How) 결정하는지에 대한 주소 할당(Address binding) 기법입니다.
Address binding에는 Compile time binding, Load time binding, Execution time binding 3가지가 존재합니다.
🧡 Compile time binding
Compile time binding은 이름 그대로 컴파일 시점에 물리 주소가 결정되는 형식의 주소 할당 기법입니다.
그림을 살펴보면 data는 논리 주소이든 물리 주소이든 0x00198000번지를 사용하고 있습니다.
즉, 우리가 프로그램을 작성하고 컴파일하는 시점에 특정 명령어들이 메인 메모리 몇 번지에 적재될 것인지 이미 결정된다는 의미입니다.
그렇기 때문에 프로그래밍을 할 때 사용하던 논리 주소와 실제 물리 주소가 동일합니다.
또한, Compile time binding은 Absolute code의 특징을 가지고 있습니다.
Absolute code는 이름 그대로 주소가 한 번 결정되면 변하지 않고 fix 된다는 의미입니다.
Compile time binding의 문제점
하지만 이러한 주소 할당 기법에는 큰 문제가 있습니다.
만약, 프로세스 A를 10000번지에 할당할 것이라고 정해놓았는데, 프로세스 B를 실행시키려고 보니 이 프로세스도 10000번지에 할당되어야 한다면 어떻게 될까요?
메모리가 뒤엉키거나 Exception이 발생하여 둘 중 한 프로세스가 예기치 못한 오류로 abort 될 것입니다.
그렇다면 Compile time binding은 언제 사용되는 것일까요?
바로, 아두이노나 임베디드 시스템에서 사용될 수 있습니다.
메모리상에 할당해야 하는 프로세스가 단 한 개라면 위와 같은 문제를 고려할 필요가 없기 때문입니다.
💛 Load time binding
Load time binding은 프로그램을 메모리에 적재시킬 때 물리 주소가 결정됩니다.
즉, 프로그램 내부에서 사용하는 논리 주소(Logical address)와 실제 메모리에 할당되는 물리 주소(Physical address)가 다르다는 것을 의미합니다.
그림을 살펴보면 왼쪽은 논리 주소 공간, 오른쪽이 물리 주소 공간을 나타내고 있습니다.
Logical address로 0x98000번지를 사용하던 data가 Physical address로는 0x198000번지를 사용하고 있습니다.
또한, 프로그램을 0x100000번지부터 시작을 하고 있습니다.
여기서 Load time binding 기법은 Logical address로 상대 주소를 사용하고 있고, Physical address로는 해당 상대 주소 + 프로그램( 또는 Segment)의 시작 주소를 더한 주소를 사용한다는 사실을 알 수 있습니다.
그렇기 때문에 Compile time binding과 다르게 논리 주소와 물리 주소가 다르며, 상대 주소를 사용하고 주소가 변하지 않는 Absolute code와 상반되는 Relocatable code의 특징을 가지고 있습니다.
Load time binding의 문제점
하지만 Load time binding에도 문제점이 존재합니다.
프로그램을 메모리에 올리는 시점에 한 번에 주소 변환을 해야 하다보니, 메모리에 프로그램을 적재하는 시간이 지나치게 오래 걸리게 됩니다.
예를 들어, code segment에 100만개의 명령어가 있다고 가정해 보겠습니다.
그럼 메모리에 적재하는 순간에 100만 개의 명령어에 code segment의 시작 주소를 모두 더하는 과정을 거쳐야 합니다.
즉, 오버헤드로 인해 배보다 배꼽이 더 큰 상황이 발생합니다.
💚 Execution time binding
이러한 문제를 해결하기 위해 등장한 것이 바로 Execution time binding입니다.
Execution time binding은 메모리에 적재할 때 한 번에 주소 변환을 하지 말고 특정 명령어를 실행하고자 할 때, 즉, 필요한 순간에 그때 그 때 변환하는 주소 할당 기법입니다.
그림처럼 논리 주소 공간과 물리 주소 공간에서 data라는 값에 대해 0x98000번지를 동일하게 사용하고 있습니다.
해당 프로그램( 또는 Segment)은 0x100000번지에서 시작하고 있습니다.
그리고 현재 접근하고자 하는 data는 물리 주소 공간의 0x98000번지에 존재합니다.
Load time binding과 동일하게 상대 주소를 사용하고 있습니다.
달라진 점을 찾자면 오른쪽에 조그마한 그림이 하나 추가 되었습니다.
저 그림이 의미하는 바는 실행 시점에 물리 주소를 Base 주소에 더해서 사용할 것이라는 것입니다.
Base 주소를 더하는 과정 또한 OS가 대신해줄 것 같지만 그렇지 않습니다.
CPU 내부에 MMU(Memory Management Unit)라는 작은 하드웨어가 존재하는데, 이 부품이 메모리의 변환을 처리합니다.
즉, (시스템) 소프트웨어가 아니라 Hardware 단에서 주소 변환을 처리한다는 것을 의미합니다.
CPU의 PC(Program Counter)에 다음 실행할 명령의 주소를 가져올 때, Main Memory에서 바로 가져오지 않고 중간에 MMU를 거치는 모습을 확인할 수 있습니다.
이 과정이 Execution time binding에서 주소를 할당하는 모습입니다.
github : https://github.com/tmdgh1592
'CS > 운영체제' 카테고리의 다른 글
[운영체제] 비연속할당(Noncontiguous allocation) - 세그먼테이션(Segmentation) (0) | 2023.01.06 |
---|---|
[운영체제] Contiguous Allocation의 문제점 - External Fragmentation(외부단편화) (1) | 2023.01.02 |
[운영체제] 식사하는 철학자들 문제 (Dining philosophers problem) - Deadlock, Starvation (8) | 2022.11.30 |
[운영체제] CPU 스케쥴러 (Short-Term, Long-Term, Midium-Term 스케쥴러) (2) | 2022.11.15 |
[운영체제] 좀비(Zombie) 프로세스와 고아(Orphan) 프로세스 (0) | 2022.11.09 |