{{위키데이터 속성 추적}}
{{X86 아키텍처}}

'''보호 모드'''(Protected mode, {{문화어|보호방식}})는 컴퓨터에서 보호 가상 주소 모드라고도 하며 x86 호환 [[중앙 처리 장치|CPU]]의 운영 방식이다. 처음에는 1982년에 [[x86]] 아키텍처에 추가되었다. 그 뒤로 [[인텔]]의 80286 (286) 프로세서로, 나중에 1985년에는 80386 (386)로 연장되었다. 보호 모드는 시스템 소프트웨어가 [[다중 작업]], [[가상 메모리]], [[페이징]], 그리고 [[응용 소프트웨어]]를 넘는 [[운영 체제]] 제어 능력을 높이기 위해 고안된 운영 체제의 다른 기능들을 이용할 수 있게 도와준다.

x86 보호 모드를 지원하는 프로세서가 전원이 켜지면 [[리얼 모드]]에서 함수를 실행하여 초기의 x86 프로세서의 뒤떨어지는 호환성을 관리하기 시작한다. 보호 모드는 시스템 소프트웨어가 몇 개의 서술자 테이블을 설정하고 제어 [[프로세서 레지스터|레지스터]] 0 (CR0)에서 프로텍션 이네이블(PE:Protection Enable) 비트를 설정한 뒤에 진입할 수 있다. 보호 모드가 추가해 놓은 개선 사항들 덕에 이 방식은 폭넓게 채택되었으며 그 뒤로 x86 아키텍처 위로 여러 향상들이 추가로 뒤따르게 되었다.

== 16비트 보호 모드 ==
16비트 보호 모드는 24비트 물리 주소 공간에 접근할 수 있으며 1 세그먼트 근처에 최대 64킬로바이트의 공간을 제공한다. 세그먼트 레지스터를 기반으로 세그먼트 방식의 가상 환경을 만든다.

보호된 공간 밖에 있는 메모리에 접근하면 바로 예외가 일어나 처리가 중지된다. 80286의 16비트 PVAM의 모든 보호 위반 예외는 [[인터럽트 벡터 테이블]] "일반 보호 예외(General Protection Fault)" INT13에만 할당할 수 있다. 이 경우, 그 동안 사용하던 프로세스로 돌아갈 수 없다. 다시 말해, 외부 저장 장치가 있는 가상 환경 시스템에서 페이지 위반을 예외로 처리하여 페이지를 스왑하고 나서 프로세스를 다시 시작할 수 없다. 세그먼트 서술자에는 쓰이지 않는 비트가 있기 때문에 이를 이용해 관리를 받을 수는 있지만, 메모리 접근 위반을 바탕으로는 관리를 받을 수 없다.

== 32비트 보호 모드 ==
32비트 보호 모드는 인텔 80386 이후부터 지원한다. 32비트의 선형 주소 공간으로 접근할 수 있고, 1 세그먼트에 최대 4 기가바이트의 공간을 제공할 뿐만 아니라, 페이지 테이블을 통해 물리 주소로 변환할 수 있고, 페이징 방식의 가상 기억을 사용할 수 있다.

한 페이지는 기본적으로 4 킬로바이트이며, 프로세스가 직접 읽어들이도록 만들어져 있는 페이지 테이블도 4 킬로바이트(1024개의 엔트리를 보관할 수 있음)이다. 이로써 4 기가바이트의 논리 공간을 모두 가리킬 수 있다. 또, 가상 86 모드는 32비트 보호 모드의 특별한 작업 가운데 하나이다.

386 이후로 보호 모드에 다음의 기능들을 지원한다:

* [[페이징]]
* 32 비트 물리 및 가상 주소 공간
* 32 비트 세그먼트 오프셋
* [[리얼 모드]]로 되돌리는 기능
* 가상 8086 방식
* 32 비트 물리 주소 공간은 80386SX와 오래된 286 버스를 사용하는 다른 386 프로세서에는 존재하지 않는다.

== 보호 모드에 들어갔다가 빠져나오기 ==
386이 나오기 전까지는 보호 모드는 보호 모드에 들어가면 [[리얼 모드]]로 되돌아가는 직접적인 방법을 제공하지 못했다. [[IBM]]사는 CPU를 다시 설정하고, [[콜 스택]](스택 포인터)이라고 부르는 시스템 레지스터를 저장하고 [[프로그래머블 인터럽트 컨트롤러|PIC]] 안에서 인터럽트 마스크의 시간을 정하는 환경을 만들었다. 이로써 BIOS가 CPU를 비슷한 상태로 되돌릴 수 있게 하여 초기화 전의 실행 코드를 시작할 수 있게 하였다.

보호 모드로 들어가려면, [[전역 서술자 테이블]] (GDT)을 적어도 다음의 세 개 항목 이상 만들어야 한다.
* NULL 서술자
* 코드 세그먼트 서술자
* 데이터 세그먼트 서술자
[[A20]] CPU가 1 메가바이트의 메모리를 넘어 접근할 수 있도록 전자 주소 라인의 나머지에 접근을 허용해야 하는데, 이때 주소 라인을 사용해야 한다.
이 두 단계를 수행하고, 286을 사용하는 경우 리얼 모드로 전환하기 위한 단계들을 개별적으로 수행한 다음, PE 비트를 CR0 레지스터 안에서 설정하고 far jump가 프리패치 입력 대기([[prefetch input queue]])를 지워 놓아야 한다.
<syntaxhighlight lang="asm">
 ; PE 비트 설정
 mov eax, cr0
 or eax, 1
 mov cr0, eax

 ; far jump (cs = 코드 세그먼트의 셀렉터)
 jmp cs:@pm

 @pm:
   ; 이제 보호 모드에 있게 됨.
</syntaxhighlight>
386의 등장으로, 보호 모드는 286에서 필요했던 초기의 설정 단계들을 수정할 필요 없이, 리얼 모드 값과 더불어 세그먼트 레지스터를 불러오고, A20 라인을 비활성화하고, CR0 레지스터 안에 있는 PE 비트를 지워 놓아야 끝을 맺을 수 있다.

== 기능 ==
보호 모드는 시스템의 안정성과 보안을 개선할 목적으로 운영 체제가 응용 소프트웨어를 더 효과적으로 제어하도록 도와 주는 수많은 새로운 기능이 있다. 이러한 추가 기능은 운영 체제가 적절한 하드웨어 지원 없이는 어렵거나 불가능할 수도 있다.

=== 권한 수준 ===
보호 모드에서는 0(가장 높은 수준)부터 3(가장 낮은 수준)까지의 4가지 권한 수준이 있다. 이러한 권한 수준은 [[링 보안|링]](ring)이라고도 불리며 이를 사용함으로써 시스템 소프트웨어가 데이터 접근, [[콜 게이트]], 권한 기능 실행에 대한 제한을 허용한다.

대부분의 환경에서 운영 체제와 몇 가지 [[장치 드라이버]]는 링 0에서 동작하며, 응용 프로그램은 링 3에서 동작한다.

=== 리얼 모드 응용 프로그램 호환성 ===
인텔 80286 프로그래머의 참조 설명서에는 다음과 같이 나와 있다.

{{인용문2|80286은 80386과 80186 응용 프로그램과 호환된다. 대부분의 8086 응용 프로그램은 보호 모드의 80286에서 다시 컴파일되거나 어셈블링된 뒤에 실행할 수 있다.
|인텔 80286 프로그래머의 참조 설명서 중}}

대부분의 경우 리얼 모드 코드의 이진 프로그램의 호환성, 최대 16MB의 물리 메모리 접근 기능, 1GiB의 [[가상 메모리]]는 응용 프로그램을 개발하는 프로그래머들에게 눈에 가장 띄는 변화였다. 응용 프로그램이 어떠한 기술에 의존한다면 실행되지 않을 수도 있었기 때문에 제한이 없는 것은 아니었다.

* 세그먼트 산술
* 권한 명령어들
* 직접 하드웨어 접근
* [[자가 수정 코드|코드 세그먼트에 기록]]
* [[데이터 실행 보호|데이터 실행]]
* 세그먼트 오버랩
* 인텔이 남겨 놓은 BIOS 인터럽트 때문에 BIOS 기능을 사용함

실제로 거의 대부분의 [[도스]]용 응용 프로그램들은 이러한 규칙을 따르지 않는다. 이러한 제한 때문에 [[가상 86모드]]가 만들어져서 80386에 공개되었다. 이러한 잠재적인 문제에도 불구하고 [[윈도우 3.x]] 뒤부터 수많은 [[윈도우 2.x]] 응용 프로그램들을 돌릴 수 있도록 리얼 모드에 대한 이진 호환성의 이점을 활용할 수 있었고 보호 모드에서 윈도 2.x의 리얼 모드에서 실행이 가능하였다.

=== 가상 8086 모드 ===
{{본문|가상 8086 모드}}

=== 페이징 ===
{{본문|페이징}}

=== 다중 작업 ===
{{본문|멀티테스킹}}

== 같이 보기 ==
* [[리얼 모드]]

== 외부 링크 ==
* [http://www.x86.org/articles/pmbasics/tspec_a1_doc.htm 보호 모드의 기초]
* [https://web.archive.org/web/20070622205752/http://www.internals.com/articles/protmode/introduction.htm 보호 모드 소개]
* [http://www.intel.com/design/intarch/papers/exc_ia.htm 인텔 아키텍처의 보호 모드]

{{메모리 관리}}
{{운영 체제}}

[[분류:X86 운영 모드]]
[[분류:프로그래밍 언어 구현]]