운영체제 스터디 6주차

낚시하는 곰·2025년 10월 14일

운영체제 스터디

목록 보기
5/10

베이스 레지스터와 바운드 레지스터

“프로세스마다 메모리 공간이 분리되어 있는 이유가 뭘까?”

바로 CPU가 베이스 레지스터(Base Register)바운드 레지스터(Bound Register) 라는 하드웨어를 통해
각 프로세스의 메모리 접근을 감시하고, 보호하기 때문이다.


1️⃣ 배경 — 모든 프로그램이 같은 메모리를 쓸 수 있었던 시절

초기의 컴퓨터에서는
모든 프로그램이 물리 메모리를 그대로 사용했다.
즉, 운영체제와 사용자 프로그램이 한 주소 공간을 공유했기 때문에,
하나의 버그가 시스템 전체를 날려버릴 수 있었다.

[물리 메모리]
|---------------------------|
| OS | 프로그램 A | 프로그램 B |
|---------------------------|
  • 프로그램 A가 실수로 B의 주소를 참조하면 B의 데이터가 덮여버림
  • 운영체제 코드 영역을 침범하면 시스템 전체가 다운됨

이 문제를 해결하기 위해 등장한 것이
“주소 변환(Address Translation)”, 그리고
그 핵심 하드웨어가 바로 Base / Bound 레지스터다.


2️⃣ 개념 — “가상 주소를 물리 주소로 바꾸는 기준점”

프로세스가 메모리를 접근할 때,
CPU는 실제 물리 주소로 바로 접근하지 않는다.

그 대신 프로세스 입장에서는
항상 0번지부터 시작하는 독립된 공간을 본다.

이 “가상 주소”를 실제 “물리 주소”로 바꿔주는 역할을
CPU의 베이스 레지스터바운드 레지스터가 맡는다.


3️⃣ 베이스 레지스터 (Base Register)

“이 프로세스의 메모리는 물리 메모리 어디서부터 시작하나요?”

  • 정의: 프로세스의 주소 공간이 실제 메모리상에서 시작되는 물리 주소
  • 기능:
    가상 주소(virtual_addr) + 베이스 값 = 물리 주소(physical_addr)

즉, 프로세스가 “0번지에 쓰기”를 시도해도
CPU는 Base + 0 주소에 접근하도록 자동 변환한다.

예시

프로세스 A: Base = 1000
프로세스 B: Base = 5000

프로세스 A가 0x0100에 접근 → 실제는 1000 + 0x0100 = 1100
프로세스 B가 0x0100에 접근 → 실제는 5000 + 0x0100 = 5100

두 프로세스 모두 “0x0100”을 썼지만,
물리 메모리상에서는 전혀 다른 영역에 접근한다.


4️⃣ 바운드 레지스터 (Bound Register)

“이 프로세스가 접근할 수 있는 최대 범위는 어디까지인가?”

  • 정의: 프로세스의 주소 공간 크기(또는 끝 주소)를 저장
  • 기능:
    접근하려는 가상 주소가 이 범위 안에 있는지 검사
  • 역할:
    잘못된 메모리 접근을 하드웨어 수준에서 차단

예시

Base = 1000
Bound = 4000 (즉, 0x0 ~ 0x0FFF까지만 유효)
  • 접근: virtual_addr = 0x0500 → OK ✅
  • 접근: virtual_addr = 0x2000 → ❌ 바운드 초과 → 예외(Exception) 발생 → 세그폴트(SIGSEGV)

이 과정은 운영체제가 아닌 CPU(MMU) 가 즉시 처리한다.
즉, 성능에 전혀 영향을 주지 않고 하드웨어가 자동으로 보호 기능을 수행한다.


5️⃣ 전체 동작 흐름

[CPU 실행 흐름]

가상 주소 요청
   ↓
가상주소 + Base → 물리주소 계산
   ↓
Bound 범위 검사
   ↓
┌───────────────┬───────────────┐
│ 유효 주소     │ 범위 초과     │
│ → 접근 허용   │ → 예외 발생   │
└───────────────┴───────────────┘

즉, 하드웨어가 “주소 변환 + 보호”를 한 번에 처리하는 구조야.
운영체제는 이 값(Base, Bound)을 세팅해주기만 하면 된다.


6️⃣ 예시 코드 (시뮬레이션)

아래는 이 원리를 단순히 시뮬레이션한 C 코드야.

#define BASE 1000
#define BOUND 4000

int translate_address(int virtual_addr) {
    if (virtual_addr < 0 || virtual_addr >= BOUND) {
        printf("Segmentation Fault! 접근 불가 주소: %d\n", virtual_addr);
        return -1;
    }
    return BASE + virtual_addr;
}

int main() {
    int vaddr = 1200;
    int paddr = translate_address(vaddr);
    if (paddr != -1)
        printf("가상주소 %d → 물리주소 %d\n", vaddr, paddr);
}

출력:

가상주소 1200 → 물리주소 2200

만약 vaddr = 5000; 이면:

Segmentation Fault! 접근 불가 주소: 5000

7️⃣ 운영체제가 이걸 어떻게 관리하나

운영체제는 프로세스마다 “메모리 맵핑 정보”를 저장해야 한다.
이를 PCB (Process Control Block) 에 기록한다.

프로세스BaseBound
A10004000
B50002000

프로세스 전환(Context Switch) 시,
운영체제는 CPU의 Base/Bound 레지스터를 PCB에 맞게 교체한다.

이로써 동시에 여러 프로세스가 돌아도
서로의 메모리를 침범할 수 없다.


8️⃣ 현대 시스템에서의 진화

과거현대의미
Base/BoundPage Table더 유연한 메모리 매핑 (비연속적 영역 가능)
단일 주소 범위다수의 페이지세그멘테이션 + 페이징 결합
단순 보호권한 비트(R/W/X)세밀한 접근 제어
CPU 검사MMU + TLB빠른 주소 변환 캐시

즉, Base/Bound는 현대 가상 메모리의 조상이자,
“프로세스 격리(isolation)”의 가장 단순한 형태다.


9️⃣ 백엔드 개발자 관점에서의 비유

OS 메커니즘백엔드 대응 개념
Base Register컨테이너 루트 디렉토리 (chroot)
Bound Registercgroup 메모리 제한
예외 발생API 403/401 Forbidden
PCB + Context Switch스레드 풀의 컨텍스트 교체

즉, 운영체제의 메모리 격리 원리 = 서버의 자원 격리 원리야.
Base/Bound는 우리가 매일 쓰는 Docker, VM, 컨테이너 격리의 기초 설계 철학이야.


마무리

Base Register는 “어디서부터 시작할지”,
Bound Register는 “어디까지 허용할지”를 정의한다.
이 두 값 덕분에 운영체제는

  • 각 프로세스의 메모리를 독립적으로 보호하고,
  • 버그나 공격으로부터 시스템 전체를 방어할 수 있다.
profile
취업 준비생 낚곰입니다!! 반갑습니다!!

0개의 댓글