Разлика между версии на „Защитен режим“

30 145 байта изтрити ,  преди 10 години
преместено в "Реален режим"
м (Робот Добавяне: uk:Захищений режим)
(преместено в "Реален режим")
#виж [[Защитен режим]]
'''Protected mode''' (на английски, буквално ''защитен режим'') е режим на работа на [[Централен процесор|компютърните процесори]] в архитектурата [[x86]]. При защитения режим, максималната адресирана памет е 4 GB (2<sup>32</sup> байта), има странициране и сегментиране на паметта, както и апаратна защита на достъпа до паметта и входно-изходното пространство. Почти всички съвременни операционни системи за x86 процесори работят изключително в защитен режим (и неговия наследник - [[long mode]], въведен с разширенията [[x86-64]]).
 
== История ==
 
Защитеният режим е въведен за пръв път в 16-битовия процесор [[80286]] на [[Intel]]. Въпреки че 80286 има апаратна защита на паметта, той наследява малкото адресно пространство на своя предшественик [[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]].
 
== Технология ==
 
Тъй като защитеният режим е базиран на [[real mode|реалния режим]] и наследява повечето му архитектурни особености, тук ще бъдат посочени само разликите с [[real mode|реалния режим]].
 
* Разширяване на всички регистри от 16 на 32 бита.
* 4 GB (2<sup>32</sup> байта) адресно пространство.
* 64 KB (2<sup>16</sup> байта) входно-изходно адресно пространство.
* Сегментиране на паметта с гъвкав размер на сегмента.
* Странициране на паметта.
* 2 нови типа данни.
* 5 нови метода за адресиране.
* Множество нови инструкции.
 
=== Регистри ===
 
При защитения режим всички регистри стават 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-битов размер и в [[real mode|реален режим]], но подразбиращият се размер е 16-битов и трябва да се използва специален префикс на иструкцията, за да се работи с 32-битовите регистри. В реален режим сегментните регистри FS и GS работят като останалите семнентни регистри и дават възможнодст за достъп до 6 16-битови сегмента наведнъж.
 
=== Типове данни ===
 
В добавка към типовете данни, които могат да бъдат обработвани в [[real mode|реален режим]], в защитения режим могат да бъдат обработвани следните типове данни:
 
* '''32-битови цели числа без знак'''. Имат диапазон на възможните стойности от 0 до 2<sup>32</sup> - 1.
 
* '''32-битови цели числа със знак'''. Имат диапазон на възможните стойности от -2<sup>31</sup> до 2<sup>31</sup> - 1.
 
* '''Стринг от байтове'''. Последователност от байтове с максимален размер до 2<sup>32</sup> - 1 байта.
 
=== Методи за адресиране ===
 
При защитения режим физическият адрес се формира по по-сложен начин в сравнение с [[Real_mode#.D0.9C.D0.B5.D1.82.D0.BE.D0.B4.D0.B8_.D0.B7.D0.B0_.D0.B0.D0.B4.D1.80.D0.B5.D1.81.D0.B8.D1.80.D0.B0.D0.BD.D0.B5|реалния режим]]. От самата инструкция се определя т.нар. ''ефективен адрес'', който се преобразува в ''линеен адрес'' чрез механизма за [[сегментиране на паметта]]. Ако не е включен механизма за [[странициране на паметта]], то линейният адрес съвпада с физическия, но ако механизмът за странициране е включен, той преобразува линейния адрес в съответния ''физически адрес''.
 
==== Формиране на адресите ====
 
Ефективният адрес при защитения режим представлява отместване в рамките на един от текущо използваните сегменти (също като при реалния режим). Ефективният адрес се определя по следния начин:
 
A = B + I * S + O,
 
където:
 
:'''A''' е полученият ефективен адрес на операнда,
 
:'''B''' е базов адрес (задава се в някой от регистрите с общо предназначение),
 
:'''I''' е индекс (задава се в някой от регистрите с общо предназначение, с изключение на ESP),
 
:'''S''' е мащаб (може да бъде 1, 2, 4 или 8) (задава се като непосредствен операнд в самата инструкция),
 
:'''O''' е отместване, което е непосредствено закодирано в самата инструкция като 8-, 16-, или 32-битово число със знак.
 
Както се вижда, адресирането при защитения режим е значително по-гъвкаво от това при реалния режим. Трябва да се има предвид, че при процесорите, които поддръжат защитения режим, горепосочените разширения в начина на адресиране са достъпни и в реален режим.
 
==== Сегментиране на паметта ====
 
Полученият по посочения в предната точка начин ефективен адрес, всъщност представлява отместване в рамките на ''сегмент'' от паметта. Докато в реалния режим сегментите се използват само като средство за преодоляване на ограниченото адресно пространство, в защитения режим сегментите служат изключително за осигуряването на апаратна защита на паметта от непозволен достъп.
 
В защитения режим сегментите са дълги до 4 GB (2<sup>32</sup> байта), като началният им адрес, размерът им и другите им атрибути са записани в така наречения ''сегментен дескриптор''. Сегментните дескриптори са подредени в таблица в паметта, наречена дескрипторна таблица. Може да има множество такива таблици, като във всеки един момент трябва да има поне 2 дефинирани таблици - глобалната дескрипторна таблица (GDT), която е една и съща за всички процеси; и локалната дескрипторна таблица (LDT), която може да е различна за всеки процес. Адресите на GDT и LDT се зареждат в специални 32-битови регистри.
 
Всяка дескрипторна таблица може да съдържа до 2<sup>13</sup> дескриптора на сегменти (2<sup>13</sup> - 1 за GDT, защото първият запис не се използва). Сегментните регистри съдържат 16-битов индекс на някои от дескрипторите в GDT или LDT. Един от битовете на индекса определя дали се прави достъп до LDT или GDT, други два определят обявеното ниво на привилегированост на сегмента (използва се при защитата на паметта), а останалите 13 бита съдържат номера на съответния дескриптор на сегмент в съответната таблица.
 
По отношение на защита на паметта, всеки сегмент има като атрибут т. нар. ниво на привилегированост (цяло число от 0 до 3, като 0 е най-привилегированото ниво). Обикновено операционната система работи на ниво 0, а потребителските програми - на ниво 3. Останалите нива не се използват при повечето съвременни операционни системи.
 
Действието на защатита на паметта може да бъде обобщено по следния начин:
 
* От дадено ниво на привилегированост може да се прави достъп до данни само в същото ниво на привилегированост или в по-малко привилегировано ниво.
* От дадено ниво на привилегированост може да се викат подпрограми и да се предава управлението само в същото ниво на привилегированост или в по-привилегировано ниво.
 
==== Странициране на паметта ====
 
Полученият след сегментирането ''линеен адрес'' съвпада с физическия адрес само ако не е включено страницирането на паметта (страницирането на паметта е опционално и може да се изключи). При включено странициране на паметта, линейният адрес се преобразува във физически по описаната по-долу схема.
 
Страниците на паметта при защитения режим са с размер 4 KB (2<sup>12</sup> байта) и са подравнени на гранците 4 KB (по-късно са въведени страници с по-голям размер - 4 MB, за да може да се използват по-големи адресни пространства). 32-битовият линеен адрес може да се разглежда като съвкупност от:
 
* Най-старшите 10 бита определят индекс в каталога на страниците, който представлява таблица от 1024 елемента в паметта. Всеки от тези елементи сочи към адреса на една от таблиците на страниците, или към началния адрес на страница от 4 MB; или е невалиден.
 
* Следващите 10 бита определят индекс на елемент в таблицата на страниците, която също има 1024 елемента, всеки от които или сочи към страница в паметта или е невалиден.
 
* Най-младшите 12 бита от адреса опреледят отместването в рамките на една страница. Ако страницата е с размер 4 MB, то най-младшите 22 бита са отместването в страницата.
 
Създаването на каталога и таблиците на страниците е задължение на операционната система, като началният адрес на каталога на страниците е записан в един от управляващите регистри на процесора.
 
Страницирането на паметта осигурява възможност за използването на [[виртуална памет]], тъй като една страница може да бъде обявена за невалидна в таблицата на страниците и всеки достъп до нея предизвиква специално прекъсване, което дава възможност на операционната система да зареди съответната страница в паметта.
 
В съвременните операционни системи за управление на паметта се използва предимно страницирането, а сегментирането почти не се използва (обикновено всички сегменти са с максимален размер и начален адрес 0, което на практика ги обезсмисля). Това се налага поради факта, че при писането на приложни и системни програми сегментирането създава много главоболия и проблеми, а страницирането е напълно невидимо за потребителските програми.
 
Защитата на паметта от гледна точка на страницирането е доста "орязана": в описанието на страницата има само 2 еднобитови флага, които осигуряват следните нива на достъп: забранен всякакъв достъп, разрешено четене и разрешено четене и запис. В по-съвременните x86 процесори (произведени след 2003 г.) е въведен т. нар. [[NX бит]], който показва дали е разрешено изпълнението на програмен код в съответната страница. Това повишава сигурността на операционната система, предотвратявайки една от най-често използваните хакерски атаки - препълването на буфер.
 
=== Входно-изходно адресно пространство ===
 
При защитения режим входно-изходното адресно пространство е със същия размер като при реалния режим (64 KB), но достъпа до него е разрешен само при определени условия:
 
* Нивото на привилегированост на текущо изпълнявания процес трябва да е по-голямо от зададеното в двубитовото поле '''IOPL''' на регистъра '''EFLAGS'''. Естествено, съдържанието на IOPL не може да се променя от задачите с ниско ниво на привилегированост.
 
* Ако предната проверка е положителна, то се прави допълнителна проверка чрез така наречената таблица за защита на входно-изходното пространство. Тази таблица съдържа по 1 бит за всеки от адресируемите 64&nbsp;536 входно-изходни порта, като този бит разрешава или забранява достъпа до съответния порт.
 
Ако някоя от горните проверки даде отрицателен резултат, следните инструкции не могат да бъдат изпълнени:
 
* '''IN''', '''OUT''', '''INS''', '''OUTS''' (правят се и двете проверки)
* '''CLI''', '''STI''' (прави се само първата проверка)
 
Както се вижда, освен достъпа до входно-изходното адресно пространство, се ограничава и способността на програмата да маскира прекъсванията, за да не може да "завземе" процесорното време, игнорирайки прекъсванията от часовника.
 
Както полето IOPL, така и таблицата за защита на входно-изходното пространство са специфични за всеки процес, която позволява на операционната система да управлява достъпа до входно-изходното пространство изключително гъвкаво.
 
=== Инструкции ===
 
Следва описание на новите инструкции в сравнение с [[Real mode#.D0.98.D0.BD.D1.81.D1.82.D1.80.D1.83.D0.BA.D1.86.D0.B8.D0.B8|реалния режим]]. Трябва да се има предвид, че повечето нови инструкции могат да се използват и в реален режим. Новите инструкции, които могат да бъдат използвани само в защитен режим, са специално отбелязани.
 
==== Инструкции за трансфер на данни ====
 
* '''MOVSX''' - разширяване на операнда от 8 до 16 или от 16 до 32 бита с отчитане на знака и прехвърляне на резултата в регистър с общо предназначение.
* '''MOVZX''' - разширяване на операнда от 8 до 16 или от 16 до 32 бита без отчитане на знака (допълване с нули отляво) и прехвърляне на резултата в регистър с общо предназначение.
* '''PUSHA''' - записване на всички регистри с общо предназначение в стека.
* '''POPA''' - зареждане на всички регистри с общо предназначение от стека.
 
==== Инструкции за побитови операции ====
 
* '''BSF''', '''BSR''' - търсене на първия ненулев бит, започвайки съответно от най-старшия и най-младшия бит на операнда.
* '''BT''' - проверка на даден бит (бита се записва в полето CF на на регистъра EFLAGS).
* '''BTC''' - също като '''BT''', като стойността на адресирания бит се променя.
* '''BTR''' - също като '''BT''', като адресираният бит се нулира.
* '''BTS''' - също като '''BT''', като адресираният бит се установява в 1.
 
==== Инструкции за работа със стрингове ====
 
* '''INS''' - зареждане на стринг от порт във входно-изходното адресно пространство.
* '''OUTS''' - запис на стринг в порт във входно-изходното адресно пространство.
 
==== Инструкции за преход ====
 
* '''ENTER''' - създаване на [[стек]] фрейм (stack frame) на подпрограма.
* '''LEAVE''' - освобождаване на стек фрейм (stack frame) на подпрограма.
* '''SETO''', '''SETNE''', '''SETB'''/'''SETNAE'''/'''SETC''', '''SETNB'''/'''SETAE'''/'''SETNC''', '''SETE'''/'''SETZ''', '''SETNE'''/'''SETNZ''', '''SETBE'''/'''SETNA''', '''SETS''', '''SETNS''', '''SETP'''/'''SETPE''', '''SETNP'''/'''SETPO''', '''SETL'''/'''SETNGE''', '''SETNL'''/'''SETGE''', '''SETLE'''/'''SETNG''', '''SETNLE'''/'''SETJG''' - условно установяване на байт.
 
==== Инструкции, работещи само в защитен режим ====
 
* '''ARPL''' - настройка на нивото на привилегированост.
* '''LAR''' - процитане на част от дескриптора на сегмент от паметта.
* '''LGDT''', '''SGDT''' - запис и четене на адреса на глобалната дескрипторна таблица в съответния регистър.
* '''LIDT''', '''SIDT''' - запис и четене на адреса на дескрипторната таблица за прекъсванията в съответния регистър.
* '''LLDT''', '''SLDT''' - запис и четене на адреса на локалната дестрипторна таблица.
* '''LMSW''', '''SMSW''' - запис и четене на младшите 16 бита на регистър CR0.
* '''LSL''' - прочитане на размера на сегмент.
* '''LTR''', '''STR''' - запис и четене на регистъра на задачата.
* '''VERR''', '''VERW''' - проверка на сегмент за право на четене и четене/запис.
 
== Проблеми ==
 
Като цяло защитеният режим е много гъвкав и напълно задоволяваше нуждите на операционните системи и приложните програми през последните 20 години. Все пак съществуват определени проблеми:
 
* 32-битовото адресно пространство дава достъп до 4 GB директно адресирирана памет. Към 2006 повечето персонални компютри все още използват значително по-малко памет, но вече не са рядкост приложенията, за които 4 GB памет са недостатъчно. Този проблем бе разрешен от 64-битовото разширение на архитектурата, наречено [[x86-64]].
 
* Повечето съвременни операционни системи не използват механизма за сегментиране на паметта, а само този за странициране на паметта. Това е проблем от гледна точка на сигурността, понеже няма начин да се забрани изпълняването на програмен код в дадена страница, ако процеса има достъп за четене до нея. Този пропуск се използва от хакерите чрез т.нар. ''атака чрез препълване на буфера'', при която се записва и изпълнява програмен код в буферите за данни на програмата. Този проблем бе разрешен с добавянето на специален флаг в дескриптора на страницата, наричан [[NX бит]].
 
* Броят на регистрите с общо предназначение на x86 процесорите винаги е бил считан за твърде малък. Свръхбързите [[кеш памет|кеш памети]] от първо ниво на съвременните процесори донякъде облекчиха този проблем, но истинско подобрение дойде с въвеждането на [[x86-64]], при което бяха добавени още 8 регистъра с общо предназначение.
 
== Приложения ==
 
Защитеният режим се използва масово във всички съвременни операционни системи и приложения за x86 процесорите. В бъдеще се очаква плавен преход към 64-битовия [[long mode]] (дълъг режим), който е пряк наследник на защитения режим. Новите операционни системи се разработват и за двата режима, но повечето приложни програми ще продължат да работят в защитен режим още дълго време, тъй като 64-битовите операционни системи могат да работят с 32-битови програми.
 
== Процесори, които поддържат protected mode ==
 
* Произведени от [[Intel]]: [[80386|386]], [[80486|486]], [[Pentium]], [[Pentium Pro]], [[Pentium II]], [[Pentium III]], [[Pentium 4]], [[Celeron]], [[Pentium M]], [[Core]], [[Core 2]], [[Xeon]].
 
* Произведени от [[AMD]]: [[Am386]], [[Am486]], [[K5]], [[K6]], [[Athlon]], [[Athlon XP]], [[Athlon 64]], [[Athlon X2]], [[Duron]], [[Sempron]], [[Opteron]], [[Geode]], [[Phenom]].
 
* Произведени от [[Cyrix]]: [[486SLC]], [[486DLC]], [[5x86]], [[6x86]], [[MII]], [[MediaGX]].
 
* Произведени от [[VIA]]: [[C3]], [[C7]].
 
== Виж също ==
 
* [[Real mode|Real mode (реален режим)]]
* [[X86|x86]]
 
== Външни препратки ==
 
* [http://home.comcast.net/~fbui/intel.html Списък с инструкциите на процесорите Intel 8086/80186/80286/386/486]
* [http://www.intel.com/design/pentiumii/manuals/243190.htm The Intel Architecture Software Developer’s Manual, Volume 1: Basic Architecture]
* [http://www.intel.com/design/pentiumii/manuals/243191.htm The Intel Architecture Software Developer’s Manual, Volume 2: Instruction Set Reference]
* [http://www.intel.com/design/pentiumii/manuals/243192.htm The Intel Architecture Software Developer’s Manual, Volume 3: System Programming]
 
[[Категория:Процесорна архитектура x86]]
 
[[ar:آلية الحماية في المعالج 80386]]
[[de:Schutzmodus]]
[[en:Protected mode]]
[[es:Modo protegido]]
[[fr:Mode protégé]]
[[ga:Mód cosanta]]
[[it:Modalità protetta]]
[[ja:プロテクトモード]]
[[ko:보호 모드]]
[[nl:Protected mode]]
[[no:Beskyttet modus]]
[[pl:Tryb chroniony]]
[[pt:Modo protegido]]
[[ru:Защищённый режим]]
[[sk:Chránený režim]]
[[tr:Protected mode]]
[[uk:Захищений режим]]
[[zh:保護模式]]