세그멘테이션에 대해 알아보기 전에 base/bound 동적 재배치의 단점에 대해 다시 상기해봅시다.
동적 재배치는 프로세스 저장 공간 통째로 메모리에 올리는걸 가정했습니다. 그리하여 내부 단편화가 일어났습니다. 즉 메모리를 효율적으로 사용하지 못했습니다.

해당 문제를 해결하기 위해 세그멘테이션이라는 기법이 생겼습니다.
세그멘테이션
프로세스의 가상 주소 공간을 논리적인 단위(세그먼트로)로 나누어 관리하는 메모리 관리 기법입니다.
우리가 기준으로 삼은 주소 공간에는 코드, 스택, 힙의 세 종류의 세그먼트가 존재합니다.


가상 주소 100번지를 참조한다고 가정해보겠습니다.
가상 주소 100번지는 코드 세그먼트에 속하게 됩니다. 물리주소로 변환화는 과정은 다음과 같습니다.
- 코드 세그먼트 시작주소
- 오프셋 = 100 - 0 = 100
- 코드 세그먼트의 크기 base = 32 KB(32768)
- 물리주소 = 32768 + 100 < 32868
- 100 < 2K -> 범위내 안전
가상 주소 4200을 참조을 참조한다고 가정해보겠습니다. 힙의 베이스인 34KB에 4200을 더하면 물리주소는 39016이 됩니다. 하지만 이것은 잘못된 계산입니다. 세그먼트의 시작점을 기준으로 오프셋을 계산해야하기 때문입니다. 즉, 주소가 참조하는 바이트가 이 세그먼트 시작으로 부터 몇번째 바이트인지 얻어야합니다.
4200은 힙의 내부 주소입니다. 즉 4200 - 4096 = 104이 오프셋이됩니다. 물리주소는 34920이 됩니다.
만약 힙의 마지막을 벗어난 잘뭇된 주소로 접근하려고한다면 프로세스를 종료시킬 가능성이 높습니다. 이를 세그먼트 폴트라고 불립니다.
세그먼트 종류의 파악
하드웨어는 변환을 위해 세그먼트 레지스터를 사용합니다. 하드웨어는 가상 주소가 어느 세그먼트를 참조하는지 그리고 그 세그먼트 안에서 오프셋은 얼마인지 어떻게 알수 있을까요??
가상 주소의 최상위 몇비트를 기준으로 주소공간을 여러 세그먼트로 나누는 것입니다.

| 00 | 코드 | 0x0000 ~ 0x0FFF (0 ~ 4095) |
| 01 | 힙 | 0x1000 ~ 0x1FFF (4096 ~ 8191) |
| 10 | (미사용/예약) | 0x2000 ~ 0x2FFF |
| 11 | 스택 | 0x3000 ~ 0x3FFF (12288 ~ 16383) |
처음 최상위 2비트를 세그먼트로사용하고 하위 12비트는 세그먼트 내의 오프셋입니다.
스택
스택 세그먼트는 다른 세그먼트와는 다르게 주소가 작아지는 방향으로 확장됩니다.
즉, 큰 주소에서 시작해서 점점 작은 주소로 내려가며 메모리를 사용합니다. 그래서 주소 변환 방식도 달라집니다.
일반적인 세그먼트는:
- 물리 주소 = Base + Offset
하지만 스택처럼 반대 방향(감소)으로 자라는 경우에는:
- 물리 주소 = Base + (음수 Offset)
즉, 현재 가상 주소가 어디에 있는지 계산한 뒤, 세그먼트 전체 크기에서 빼서 음수 오프셋을 만들어야 합니다.
가상 주소 15KB에 접근할 때를 가정해 봅시다.
- 현재 접근하려는 주소: 15KB = 15360 = 0x3C00 = 11 1100 0000 0000 (2진수)
- 상위 2비트 11를 사용하여 세그먼트를 지정하면 3KB오프셋이 남습니다.
- 3KB - 4Kb(세그먼트 최대크기) = -1
공유 자원
세그먼테이션 기법이 발전함에 따라 시스템 설계자들은 메모리를 절약하기 위해 주소 공간들 간에 특정 메모리 세그먼트를 공유하게 하였습니다. 코드 공유가 가장 일반적입니다. 크롬 브라우저를 여러 개 띄워도, 코드 내용은 같으니 같은 메모리 블록을 재사용 가능한 것입니다.
이렇게 한다면 여러 프로세스가 동일한 코드를 따로따로 로드하지 않아도 됩니다.
문제는 프로세스는 각각의 독립성을 띄워야합니다. 그래서 공유하는 세그먼트에는 쓰기 금지 같은 제한을 걸 수 있어야합니다.
세그멘트마다 protection bit를 추가하여 세그멘트를 읽거나 쓸 수 있는지 혹은 세그멘트의 코드를 실행시킬 수 있는지를 나타냅니다.
코드 세그먼트를 읽기 전용으로 설정하면 주소 공간의 독립성을 유지하면서 여러 프로세스가 주소 공간의 일부를 공유 할 수 있습니다.
세그먼테이션 주소 변환
세그멘테이션을 위한 세그먼트 테이블이 존재합니다. 세그먼트 테이블은 번호와 시작주소, 세그먼트 크기를 엔트리로 갖습니다.
물리주소는 base[s] + d로 계산됩니다.

하지만 세그먼트도 단점이 존재합니다. 아래의 상황을 가정해보겠습니다.
새로운 프로세스가 생성되어 20KB를 할당하려고 합니다. 24KB의 빈공간이 존재하지만 하나의 연속된 공간이 아니라 세개의 청크로 나누어져 있습니다. 운영체제는 20KB의 요청을 충족시킬 수 없습니다. 논리적인 단위로 나누기에 세그먼트의 크기는 다양하게 나타납니다.
이로 인해 다양한 hole이 발생하게 됩니다. 즉, 외부 단편화 문제가 생기게 됩니다.

'CS > OS' 카테고리의 다른 글
| [OS] 여유 공간 관리 (0) | 2025.05.19 |
|---|---|
| [OS] 메모리 관리 - 동적 재배치 (Base / Bound) (0) | 2025.05.08 |
| [OS] Proportional Share(비례 배분) 스케줄러 (0) | 2025.04.15 |
| [OS] 멀티 레벨 피드백 큐 (0) | 2025.03.07 |
| [OS] CPU 스케줄링 (0) | 2025.03.06 |