Защитен режим (на английски: protected mode) е режим на работа на компютърните процесори в архитектурата x86. При защитения режим максималната адресирана памет е 4 GB (232 байта), има странициране и сегментиране на паметта, както и апаратна защита на достъпа до паметта и входно-изходното пространство. Почти всички съвременни операционни системи за x86 процесори работят изключително в защитен режим (и неговия наследник – long mode, въведен с разширенията x86-64).
Защитеният режим е въведен за пръв път в 16-битовия процесор 80286 на Intel. Въпреки че 80286 има апаратна защита на паметта, той наследява малкото адресно пространство на своя предшественик Intel 8086 и в резултат 16-битовият защитен режим не получава широко разпространение (дори се стига до това, че в следващите процесори от семейството x86 няма обратна съвместимост със 16-битовия защитен режим на 286).
През 1985 г. Intel пуска на пазара първия 32-битов x86 процесор 80386, който поддържа 32-битовия защитен режим. Към средата на 90-те години на 20 век Microsoft започва да използва предимно 32-битов код в своите операционни системи и оттогава нататък 32-битовият защитен режим става основен режим на работа на x86 процесорите.
Към 2006 г. все още над 95% от софтуера за x86 процесори работи в 32-битовия защитен режим, но започват да се появяват операционни системи и приложни програми, които работят в новия 64-битов защитен режим, въведен от AMD под името long mode.
Тъй като защитеният режим е базиран на реалния режим и наследява повечето му архитектурни особености, тук ще бъдат посочени само разликите с реалния режим.
При защитения режим всички регистри стават 32-битови, а имената им се образуват от префикса E и името на съответния 16-битов регистър. 32-битовите регистри с общо предназначение са EAX, EBX, ECX, EDX, ESP, EBP, EDI и ESI, флаговият регистър е EFLAGS, а програмият брояч – EIP. Сегментните регистри си остават 16-битови (но адресът се формира по друг начин), като към вече съществуващите CS, DS, SS и ES се прибавят два нови сегментни регистъра, наречени FS и GS.
Няма директен начин за достъп до старшите 16 бита на 32-битовите регистри EAX, EBX, ECX и EDX, но се запазва възможността за директен достъп до младшия и старшия байт на младшите 16 бита под имената AL, AH, BL, BH и т.н.
Всички нови регистри са достъпни в пълния им 32-битов размер и в реален режим, но подразбиращият се размер е 16-битов и трябва да се използва специален префикс на инструкцията, за да се работи с 32-битовите регистри. В реален режим сегментните регистри FS и GS работят като останалите сегментни регистри и дават възможност за достъп до 6 16-битови сегмента наведнъж.
В добавка към типовете данни, които могат да бъдат обработвани в реален режим, в защитения режим могат да бъдат обработвани следните типове данни:
При защитения режим физическият адрес се формира по по-сложен начин в сравнение с реалния режим. От самата инструкция се определя т.нар. ефективен адрес, който се преобразува в линеен адрес чрез механизма за сегментиране на паметта. Ако не е включен механизма за странициране на паметта, то линейният адрес съвпада с физическия, но ако механизмът за странициране е включен, той преобразува линейния адрес в съответния физически адрес.
Ефективният адрес при защитения режим представлява отместване в рамките на един от текущо използваните сегменти (също като при реалния режим). Ефективният адрес се определя по следния начин:
A = B + I * S + O,
където:
Както се вижда, адресирането при защитения режим е значително по-гъвкаво от това при реалния режим. Трябва да се има предвид, че при процесорите, които поддръжат защитения режим, горепосочените разширения в начина на адресиране са достъпни и в реален режим.
Полученият по посочения в предната точка начин ефективен адрес, всъщност представлява отместване в рамките на сегмент от паметта. Докато в реалния режим сегментите се използват само като средство за преодоляване на ограниченото адресно пространство, в защитения режим сегментите служат изключително за осигуряването на апаратна защита на паметта от непозволен достъп.
В защитения режим сегментите са дълги до 4 GB (232 байта), като началният им адрес, размерът им и другите им атрибути са записани в така наречения сегментен дескриптор. Сегментните дескриптори са подредени в таблица в паметта, наречена дескрипторна таблица. Може да има множество такива таблици, като във всеки един момент трябва да има поне 2 дефинирани таблици – глобалната дескрипторна таблица (GDT), която е една и съща за всички процеси; и локалната дескрипторна таблица (LDT), която може да е различна за всеки процес. Адресите на GDT и LDT се зареждат в специални 32-битови регистри.
Всяка дескрипторна таблица може да съдържа до 213 дескриптора на сегменти (213 – 1 за GDT, защото първият запис не се използва). Сегментните регистри съдържат 16-битов индекс на някои от дескрипторите в GDT или LDT. Един от битовете на индекса определя дали се прави достъп до LDT или GDT, други два определят обявеното ниво на привилегированост на сегмента (използва се при защитата на паметта), а останалите 13 бита съдържат номера на съответния дескриптор на сегмент в съответната таблица.
По отношение на защита на паметта, всеки сегмент има като атрибут т. нар. ниво на привилегированост (цяло число от 0 до 3, като 0 е най-привилегированото ниво). Обикновено операционната система работи на ниво 0, а потребителските програми – на ниво 3. Останалите нива не се използват при повечето съвременни операционни системи.
Действието на защатита на паметта може да бъде обобщено по следния начин:
Полученият след сегментирането линеен адрес съвпада с физическия адрес само ако не е включено страницирането на паметта (страницирането на паметта е опционално и може да се изключи). При включено странициране на паметта, линейният адрес се преобразува във физически по описаната по-долу схема.
Страниците на паметта при защитения режим са с размер 4 KB (212 байта) и са подравнени на гранците 4 KB (по-късно са въведени страници с по-голям размер – 4 MB, за да може да се използват по-големи адресни пространства). 32-битовият линеен адрес може да се разглежда като съвкупност от:
Създаването на каталога и таблиците на страниците е задължение на операционната система, като началният адрес на каталога на страниците е записан в един от управляващите регистри на процесора.
Страницирането на паметта осигурява възможност за използването на виртуална памет, тъй като една страница може да бъде обявена за невалидна в таблицата на страниците и всеки достъп до нея предизвиква специално прекъсване, което дава възможност на операционната система да зареди съответната страница в паметта.
В съвременните операционни системи за управление на паметта се използва предимно страницирането, а сегментирането почти не се използва (обикновено всички сегменти са с максимален размер и начален адрес 0, което на практика ги обезсмисля). Това се налага поради факта, че при писането на приложни и системни програми сегментирането създава много главоболия и проблеми, а страницирането е напълно невидимо за потребителските програми.
Защитата на паметта от гледна точка на страницирането е доста „орязана“: в описанието на страницата има само 2 еднобитови флага, които осигуряват следните нива на достъп: забранен всякакъв достъп, разрешено четене и разрешено четене и запис. В по-съвременните x86 процесори (произведени след 2003 г.) е въведен т. нар. NX бит, който показва дали е разрешено изпълнението на програмен код в съответната страница. Това повишава сигурността на операционната система, предотвратявайки една от най-често използваните хакерски атаки – препълването на буфер.
При защитения режим входно-изходното адресно пространство е със същия размер като при реалния режим (64 KB), но достъпа до него е разрешен само при определени условия:
Ако някоя от горните проверки даде отрицателен резултат, следните инструкции не могат да бъдат изпълнени:
Както се вижда, освен достъпа до входно-изходното адресно пространство, се ограничава и способността на програмата да маскира прекъсванията, за да не може да „завземе“ процесорното време, игнорирайки прекъсванията от часовника.
Както полето IOPL, така и таблицата за защита на входно-изходното пространство са специфични за всеки процес, която позволява на операционната система да управлява достъпа до входно-изходното пространство изключително гъвкаво.
Следва описание на новите инструкции в сравнение с реалния режим. Трябва да се има предвид, че повечето нови инструкции могат да се използват и в реален режим. Новите инструкции, които могат да бъдат използвани само в защитен режим, са специално отбелязани.
Като цяло защитеният режим е много гъвкав и напълно задоволяваше нуждите на операционните системи и приложните програми през последните 20 години. Все пак съществуват определени проблеми:
Защитеният режим се използва масово във всички съвременни операционни системи и приложения за x86 процесорите. В бъдеще се очаква плавен преход към 64-битовия long mode (дълъг режим), който е пряк наследник на защитения режим. Новите операционни системи се разработват и за двата режима, но повечето приложни програми ще продължат да работят в защитен режим още дълго време, тъй като 64-битовите операционни системи могат да работят с 32-битови програми.