맨위로가기

X86 메모리 분할

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

x86 메모리 분할은 x86 아키텍처에서 메모리를 관리하는 기술로, 리얼 모드, 보호 모드, 롱 모드 등 다양한 방식으로 발전해 왔다. 초기 리얼 모드에서는 세그먼트 크기가 64KB로 제한되었지만, 80286의 보호 모드와 80386 이후의 페이징 유닛 도입을 통해 메모리 보호 기능과 가상 메모리 지원이 강화되었다. x86-64 아키텍처의 롱 모드에서는 세그먼테이션이 무력화되는 경향이 있으며, FS 및 GS 세그먼트 레지스터는 운영체제에서 특수한 목적으로 사용된다. 세그먼테이션은 코드, 데이터, 시스템 세그먼트 정의 및 권한 설정을 통해 메모리 접근을 제어하며, 운영체제와 응용 프로그램에서 다양한 용도로 활용된다.

더 읽어볼만한 페이지

  • x86 메모리 관리 - 고위 메모리 영역
    고위 메모리 영역은 80286 프로세서 이후 컴퓨터에서 1MB 이상의 메모리 공간에 접근하는 기술로, A20 주소선 활성화, BIOS 루틴 저장, A20 게이트 제어를 통해 구현되었으며, 윈도우/286, DR-DOS, MS-DOS 등에서 HMA를 활용하여 시스템 성능을 향상시켰다.
X86 메모리 분할
x86 메모리 분할
종류메모리 분할
아키텍처x86
설계인텔
도입 시기1979년 (인텔 8086)
분할 레지스터cs
ds
ss
es
fs
gs
모드실제 모드
보호 모드
시스템 관리 모드
가상 8086 모드
관련페이지 분할
메모리 관리 장치

2. 역사

x86 아키텍처의 메모리 세그먼테이션은 CPU 종류와 시대에 따라 발전해왔으며, 주요 모드로는 리얼 모드, 보호 모드, 롱 모드가 있다.


  • 리얼 모드: 인텔 8086 및 8088 프로세서에서 사용된 초기 방식으로, 16비트 세그먼트 레지스터와 오프셋을 조합하여 20비트 물리 주소를 생성, 1MB의 메모리 주소 공간을 사용.
  • 보호 모드: 80286 프로세서에서 도입, 메모리 보호 및 가상 메모리 기능을 제공하여 운영체제의 안정성과 보안성을 향상. 80286 보호 모드는 24비트(16MB) 주소 공간을 지원하며, 세그먼트 레지스터는 세그먼트 디스크립터 테이블의 인덱스를 가리킴. 80386 프로세서에서는 페이징 유닛이 추가, 주소 변환이 두 단계로, 주소 오프셋과 세그먼트 베이스가 32비트로 확장.
  • 롱 모드 (64비트 모드): x86-64 아키텍처에서 사용, 대부분의 세그먼트 레지스터는 기본 주소 0과 264 제한을 가지도록 설정, FS 및 GS 세그먼트 레지스터는 운영 체제가 특수 목적으로 사용가능.

2. 1. 리얼 모드

인텔 8086 및 8088 프로세서에서 사용된 메모리 관리 방식이다. 리얼 모드는 16비트 세그먼트 레지스터와 16비트 오프셋을 결합하여 20비트 물리 주소를 생성한다.

리얼 모드에서 세그먼트의 크기는 1바이트에서 최대 64KB까지 가능하다. 세그먼트 레지스터의 16비트 세그먼트 셀렉터는 세그먼트 주소라고 하는 20비트 선형 주소의 최상위 16비트로 해석되며, 나머지 4개의 최하위 비트는 모두 0이다.

리얼 모드의 유효 20비트 주소 공간메모리 주소 접근을 1MB로 제한한다. 이는 20개의 주소 버스 핀을 가진 인텔 8086과 8088의 하드웨어 설계에서 직접 파생되었다.

16비트 리얼 모드에서는 64KB 세그먼트보다 더 많은 메모리에 접근하기 위해 여러 메모리 세그먼트를 사용하는 것이 매우 복잡했다. 그 이유는 전체 메모리 범위를 플랫 주소 지정하는 데 적합한 주소 산술 명령어가 없었기 때문이다.

''메모리 모델'' 개념은 세그먼트 레지스터 설정에서 파생된다. 예를 들어, ''작은 모델''은 프로그램의 코드, 데이터 및 스택이 모두 단일 64KB 세그먼트에 포함된다. ''작은'' 메모리 모델에서는 데이터와 스택이 모두 동일한 세그먼트에 있고, CS는 최대 64KB의 다른 코드 세그먼트를 가리킨다.

2. 1. 1. 리얼 모드의 주소 계산



리얼 모드가상 86모드에서 세그먼트의 크기는 언제나 65,536 바이트(16 비트 오프셋을 사용)이다.

세그먼트 레지스터의 16비트 세그먼트 셀렉터(segment selector)는 20비트로 이루어진 선형주소의 최상위 16비트를 해석한 것이며, 나머지 네 개의 최하위 비트들이 모두 0인 부분까지 포함하여 세그먼트 주소라고 부른다.

세그먼트 주소는 리얼 모드 내에서 물리 주소와 동일한 ''선형'' 주소를 얻기 위해 16비트의 오프셋을 더한다. 예를 들어, 세그먼트 주소 06EFh:1234h(16진수)에서 세그먼트 셀렉터인 06EFh를 세그먼트 주소로 표현하면 06EF0h이고, 여기에 오프셋을 더하면 06EF0h + 1234h = 08124h(16진수) 와 같은 식으로 선형주소가 계산된다.

세그먼트 주소와 오프셋을 더하는 방식 때문에 단일 선형 주소를 최대 212 = 4096개의 개별 세그먼트:오프셋 쌍에 매핑할 수 있다. 예를 들어, 선형 주소 08124h는 세그먼트 주소 06EFh:1234h, 0812h:0004h, 0000h:8124h 등을 가질 수 있다.

  0000 0110 1110 11110000세그먼트16비트, 4비트 왼쪽으로 이동(또는 0x10으로 곱함)
+      0001 0010 0011 0100오프셋16비트
                            
  0000 1000 0001 0010 0100주소20비트



(선형 주소, 세그먼트 주소, 세그먼트 및 오프셋 필드의 선행 0은 명확성을 위해 여기에 표시된다. 일반적으로 생략된다.)

각 세그먼트는 선형(플랫) 주소 공간의 시작 부분에서 16 바이트의 배수인 ''단락''에서 시작한다. 즉, 16 바이트 간격이다. 모든 세그먼트가 64 KB이므로 세그먼트 간에 중첩이 발생할 수 있고 선형 메모리 주소 공간의 모든 위치에 많은 세그먼트:오프셋 쌍으로 접근할 수 있다. 선형 주소 공간에서 세그먼트 시작 위치는 세그먼트×16으로 계산할 수 있다. 0Ch(12)의 세그먼트 값은 선형 주소 공간에서 C0h(192)에 선형 주소를 제공한다. 그런 다음 주소 오프셋을 이 숫자에 더할 수 있다. 0Ch:0Fh(12:15)는 C0h+0Fh=CFh(192+15=207)이며 CFh(207)는 선형 주소이다. 이러한 주소 변환은 CPU의 세분화 장치에 의해 수행된다. 마지막 세그먼트 FFFFh(65535)는 선형 주소 FFFF0h(1048560)에서 시작하며, 20 비트 주소 공간의 끝에서 16 바이트 전이므로 최대 65,536 바이트의 오프셋으로 20 비트 8088 주소 공간의 끝에서 65,520(65536−16) 바이트까지 접근할 수 있다. 8088에서는 이러한 주소 접근이 주소 공간의 시작 부분으로 래핑되어 65535:16은 주소 0에 접근하고 65533:1000은 선형 주소 공간의 주소 952에 접근했다.

2. 2. 보호 모드



보호 모드는 80286 프로세서에서 처음 도입된 메모리 관리 기법이다. 80286의 보호 모드는 메모리 보호 기능을 제공하고, 가상 메모리 개념을 지원하여 운영체제의 안정성과 보안성을 향상시켰다.

80286 보호 모드에서는 주소 공간이 224 바이트(16MB)로 확장되었다. 16비트 세그먼트 레지스터는 세그먼트 디스크립터 테이블의 인덱스를 가리키며, 각 디스크립터는 24비트 기본 주소를 포함하여 오프셋과 함께 실제 메모리 위치를 계산하는 데 사용되었다.

80386 프로세서에서는 보호 모드가 더욱 발전했다. 80286 보호 모드의 세분화 메커니즘을 유지하면서도, 페이징 유닛을 추가하여 주소 변환 과정을 두 단계로 나누었다. 또한 주소 오프셋과 세그먼트 베이스가 32비트(80286은 24비트)로 확장되어 더 넓은 메모리 공간을 사용할 수 있게 되었다. 80386은 기존 세그먼트 레지스터 외에 FS와 GS라는 두 개의 새로운 범용 데이터 세그먼트 레지스터를 추가했다.

2. 2. 1. 80286 보호 모드

80286보호 모드는 프로세서의 주소 공간을 224 바이트(16MB)로 확장했지만, 시프트 값을 조정하는 방식은 아니었다. 대신, 16비트 세그먼트 레지스터는 이제 오프셋이 추가되는 24비트 기본 주소를 포함하는 세그먼트 디스크립터 테이블의 인덱스를 포함한다. 이전 소프트웨어를 지원하기 위해 프로세서는 8086의 세그먼트 방식 주소 지정 모델을 사용하는 "리얼 모드"로 시작한다. 그러나 약간의 차이점이 있는데, 결과적인 물리적 주소가 더 이상 20 비트로 잘리지 않으므로 리얼 모드 포인터(하지만 8086 포인터는 아님)는 이제 10000016에서 10FFEF16 사이의 주소를 참조할 수 있다. 이 약 64KB의 메모리 영역은 확장 메모리 영역(HMA)으로 알려졌으며, 이후 버전의 MS-DOS는 이를 사용하여 사용 가능한 "기본" 메모리(즉, 처음 MB 내)를 늘릴 수 있었다. HMA가 추가되면서 총 주소 공간은 약 1.06MB가 되었다. 80286은 리얼 모드 주소를 20 비트로 자르지 않지만, 80286을 포함하는 시스템은 21번째 주소 라인인 A20 라인을 차단하여 프로세서 외부의 하드웨어로 그렇게 할 수 있다. IBM PC/AT는 이를 수행하는 하드웨어를 제공했으며(원래 IBM PC 및 PC/XT 모델용 소프트웨어와의 완벽한 하위 호환성을 위해), 이후 모든 "AT-클래스" PC 호환 기종도 마찬가지였다.

286 보호 모드는 8086/88 기기를 가진 많은 사용자를 배제했기 때문에 거의 사용되지 않았다. 또한, 여전히 리얼 모드에서와 같이 메모리를 64KB 세그먼트로 분할해야 했다. 이 제한은 32비트 CPU에서 64KB보다 큰 메모리 포인터를 사용할 수 있으므로 해결할 수 있지만, 세그먼트 제한 필드는 24비트 길이이므로 생성할 수 있는 최대 세그먼트 크기는 16MB이다(페이징을 사용하여 더 많은 메모리를 할당할 수 있지만, 개별 세그먼트는 16MB를 초과할 수 없다). 이 방법은 Windows 3.x 응용 프로그램에서 평탄한 메모리 공간을 생성하는 데 일반적으로 사용되었지만, OS 자체가 여전히 16비트였으므로 API 호출은 32비트 명령으로 수행할 수 없었다. 따라서 API 호출을 수행하는 모든 코드는 64KB 세그먼트에 배치해야 했다.

286 보호 모드가 호출되면 하드웨어 리셋을 수행하는 경우 외에는 종료할 수 없었다. IBM PC/AT 표준을 따르는 기기는 표준화된 키보드 컨트롤러를 통해 CPU에 리셋을 가장할 수 있었지만, 이는 상당히 느렸다. Windows 3.x는 CPU의 인터럽트 처리 메커니즘에서 트리플 폴트를 의도적으로 유발하여 이 두 가지 문제를 해결했으며, 이는 CPU가 거의 즉시 리얼 모드로 돌아가게 했다.[2]

2. 2. 2. 80386 보호 모드

인텔 80386 프로세서와 그 이후 프로세서에서 보호 모드는 80286 보호 모드의 세분화 메커니즘을 유지하지만, 페이징 유닛이 세분화 유닛과 물리적 버스 사이에 주소 변환의 두 번째 계층으로 추가되었다. 주소 오프셋은 32비트(16비트 대신)이고, 각 세그먼트 디스크립터의 세그먼트 베이스도 32비트(24비트 대신)로 확장되었다. 세분화 유닛의 일반적인 작동은 변경되지 않았다. 페이징 유닛은 활성화하거나 비활성화할 수 있는데, 비활성화된 경우 작동은 80286과 동일하다. 페이징 유닛이 활성화된 경우, 세그먼트의 주소는 80286에서처럼 물리적 주소가 아닌 가상 주소이다. 즉, 세그먼트 시작 주소, 오프셋, 그리고 두 주소를 더하여 세분화 유닛이 파생한 최종 32비트 주소는 페이징 유닛이 활성화되었을 때 모두 가상(또는 논리적) 주소이다. 세분화 유닛이 이러한 32비트 가상 주소를 생성하고 검증하면, 활성화된 페이징 유닛이 마침내 이러한 가상 주소를 물리적 주소로 변환한다. 물리적 주소는 386에서 32비트이지만, 물리적 주소 확장을 지원하는 최신 프로세서에서는 더 클 수 있다.

80386은 또한 네 개의 기존 세그먼트 레지스터(CS, DS, ES, SS)에 두 개의 새로운 범용 데이터 세그먼트 레지스터인 FS와 GS를 도입했다.

386 CPU는 CR0 제어 레지스터의 비트를 지움으로써 다시 리얼 모드로 전환할 수 있지만, 이는 보안과 견고성을 강화하기 위한 특권적인 작업이다. 비교하자면, 286은 트리플 폴트 또는 외부 하드웨어를 사용하여 프로세서 리셋을 강제하는 방식으로만 리얼 모드로 되돌릴 수 있었다.

2. 3. 롱 모드 (64비트 모드)

x86-64 아키텍처는 롱 모드(64비트 모드)에서 세그멘테이션을 거의 사용하지 않는다. CS, SS, DS, ES의 4개 세그먼트 레지스터는 기본 주소 0으로 강제 설정되고, 제한은 264로 설정된다. FS 및 GS 세그먼트 레지스터는 여전히 0이 아닌 기본 주소를 가질 수 있다. 이를 통해 운영 체제는 이러한 세그먼트를 특수한 목적으로 사용할 수 있다. 레거시 모드에서 사용되는 글로벌 디스크립터 테이블 메커니즘과 달리, 이러한 세그먼트의 기본 주소는 모델별 레지스터에 저장된다. x86-64 아키텍처는 또한 커널 모드와 사용자 모드 기본 주소를 교환할 수 있는 특수한 ''SWAPGS'' 명령어를 제공한다.

예를 들어, x86-64의 마이크로소프트 윈도우는 GS 세그먼트를 사용하여 각 스레드에 대한 작은 데이터 구조인 스레드 환경 블록을 가리키며, 여기에는 예외 처리, 스레드 로컬 변수 및 기타 스레드별 상태에 대한 정보가 포함되어 있다. 마찬가지로, 리눅스 커널은 GS 세그먼트를 사용하여 CPU별 데이터를 저장한다.

GS/FS는 또한 GCC의 스레드 로컬 저장소 및 카나리아 기반 스택 보호에도 사용된다.

3. 세그먼테이션의 활용

x86 아키텍처에서 세그먼테이션은 다양한 방식으로 활용되어 왔다.
운영체제세그먼테이션은 운영체제가 메모리 보호, 가상 메모리, 멀티태스킹과 같은 핵심 기능을 구현하는 데 중요한 역할을 한다.


  • 메모리 보호: 각 세그먼트는 접근 권한 (읽기 전용, 읽기/쓰기, 실행 등)을 가질 수 있어, 운영체제는 사용자 프로그램이 허가되지 않은 메모리 영역에 접근하는 것을 방지할 수 있다. 이를 통해 시스템 안정성과 보안을 강화한다.
  • 가상 메모리: 세그먼테이션을 통해 실제 물리 메모리보다 더 큰 주소 공간을 프로그램에 제공할 수 있다. 이는 프로그램이 실제 메모리 크기의 제약 없이 실행될 수 있도록 한다.
  • 멀티태스킹: 각 프로그램에 독립적인 세그먼트를 할당함으로써, 운영체제는 여러 프로그램을 동시에 실행하면서도 서로 간섭하지 않도록 보장할 수 있다.

응용 프로그램초기 x86 시스템에서 세그먼테이션은 응용 프로그램 개발에도 활용되었다.

  • 메모리 접근 확장: 16비트 환경에서는 64KB 이상의 메모리에 접근하기 위해 세그먼테이션이 필수적이었다.
  • 데이터 구조 관리: 여러 데이터 구조를 별도의 세그먼트에 배치하여 관리의 효율성을 높일 수 있었다.

최신 시스템 (x86-64)64비트 환경인 x86-64 아키텍처에서는 대부분의 세그먼테이션 기능이 비활성화되어 있다. CS, SS, DS, ES 레지스터는 기본 주소 0으로 설정되고, 제한은 264로 설정되어 사실상 세그먼테이션이 없는 플랫 메모리 모델을 사용한다.

하지만, FS 및 GS 레지스터는 여전히 특별한 용도로 활용된다.

  • 마이크로소프트 윈도우: GS 세그먼트를 사용하여 각 스레드의 스레드 환경 블록을 가리킨다. 여기에는 예외 처리, 스레드 로컬 변수 등 스레드별 정보가 저장된다.
  • 리눅스 커널: GS 세그먼트를 사용하여 CPU별 데이터를 저장한다. 또한, GCC의 스레드 로컬 저장소 및 카나리아 기반 스택 보호에도 사용된다.

x86-32x86-32 프로세서에서는 세분화를 해제할 수 없다. 따라서 많은 32비트 운영 체제는 모든 세그먼트의 베이스를 0으로 설정하여 세분화를 프로그램에 무해하게 만들어 플랫 메모리 모델을 시뮬레이션한다. 예를 들어, 리눅스 커널은 다음과 같이 단 4개의 범용 세그먼트만 설정한다.

이름설명베이스제한DPL
__KERNEL_CS커널 코드 세그먼트04 GiB0
__KERNEL_DS커널 데이터 세그먼트04 GiB0
__USER_CS사용자 코드 세그먼트04 GiB3
__USER_DS사용자 데이터 세그먼트04 GiB3



리눅스는 GS를 사용하여 스레드 로컬 스토리지를 가리킨다.
보호 모드보호 모드에서 코드는 CS(코드 세그먼트 선택자)를 *제외*하고 모든 세그먼트 레지스터를 항상 수정할 수 있다. 프로세서의 현재 권한 레벨(CPL)이 CS 레지스터의 하위 2 비트에 저장되기 때문이다.

4. 세그먼테이션과 한국의 IT 환경

초기 한국의 PC 환경은 주로 16비트 운영체제인 MS-DOS를 기반으로 하였다. MS-DOS 환경에서는 리얼 모드의 세그먼테이션이 사용되었는데, 이는 640KB 기본 메모리 제한을 극복하기 위한 EMS나 XMS와 같은 기술들과 함께 사용되었다.

윈도우 9x 시리즈까지도 리얼 모드와의 호환성을 유지하기 위해 세그먼테이션의 일부 기능이 남아있었다. 그러나 32비트 및 64비트 운영체제가 보편화되면서 세그먼테이션의 중요성은 감소하였다.

하지만 운영체제 커널 수준에서는 여전히 메모리 관리를 위해 세그먼테이션이 활용되고 있다.

5. 비판 및 한계

x86 아키텍처의 메모리 분할 방식은 다음과 같은 비판과 한계를 갖는다.


  • 복잡성: 메모리 세그먼테이션은 메모리 관리를 복잡하게 만들어 프로그래머에게 부담을 준다. 특히 리얼 모드에서는 세그먼트와 오프셋을 조합하여 물리 주소를 계산해야 하므로 프로그래밍이 더 어려워진다.
  • 성능 저하: 세그먼트 기반 메모리 접근은 세그먼트 주소와 오프셋을 더하는 추가 연산을 필요로 하므로 성능 저하를 유발할 수 있다.
  • 호환성 문제: 리얼 모드와 보호 모드 간 전환은 복잡하며, 하위 호환성을 유지하기 위해 추가적인 노력이 필요하다. 예를 들어 8088 프로세서에서 발생했던 주소 래핑(address wrapping) 문제는 이후 CPU 세대에서 게이트 A20 호환성 문제를 야기했다.


16비트 리얼 모드에서는 여러 메모리 세그먼트를 사용하여 64KB 이상의 메모리에 접근하는 것이 매우 복잡했다. 이는 전체 메모리 범위를 플랫 주소 지정하는 데 적합한 주소 연산 명령어가 부족했기 때문이다. 여러 명령어를 조합하여 플랫 주소 지정을 구현할 수는 있었지만, 프로그램 속도가 느려졌다.

메모리 모델은 세그먼트 레지스터 설정에서 파생된다. 예를 들어 '작은 모델'에서는 코드, 데이터, 스택이 모두 단일 64KB 세그먼트에 포함되는 반면, '소형 모델'에서는 데이터와 스택이 동일 세그먼트에 있고 코드는 최대 64KB의 다른 세그먼트를 가리킨다.

참조

[1] 서적 IA-32 Intel Architecture Software Developer's Manual Volume 1: Basic Architecture http://www.intel.com[...] 2004-01-01
[2] 웹사이트 DevBlogs http://blogs.msdn.co[...]
[3] 서적 Intel 64 and IA-32 Architectures Software Developer's Manual Intel 2011-01-01
[4] 문서
[5] 서적 Intel 64 and IA-32 Architectures Software Developer's Manual Intel 2011-01-01
[6] 서적 IA-32 Intel Architecture Software Developer's Manual Volume 1: Basic Architecture http://www.intel.com[...] 2004-01-01



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com