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

м
замяна с n-тире
м (-и век ---> век ; козметични промени)
м (замяна с n-тире)
=== Регистри ===
 
При защитения режим всички регистри стават 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-битови цели числа без знак'''. Имат диапазон на възможните стойности от 0 до 2<sup>32</sup> - 1.
 
* '''32-битови цели числа със знак'''. Имат диапазон на възможните стойности от -2<sup>31</sup> до 2<sup>31</sup> - 1.
 
* '''низ от байтове'''. Последователност от байтове с максимален размер до 2<sup>32</sup> - 1 байта.
 
=== Методи за адресиране ===
Полученият по посочения в предната точка начин ефективен адрес, всъщност представлява отместване в рамките на ''сегмент'' от паметта. Докато в реалния режим сегментите се използват само като средство за преодоляване на ограниченото адресно пространство, в защитения режим сегментите служат изключително за осигуряването на апаратна защита на паметта от непозволен достъп.
 
В защитения режим сегментите са дълги до 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; или е невалиден.
В съвременните операционни системи за управление на паметта се използва предимно страницирането, а сегментирането почти не се използва (обикновено всички сегменти са с максимален размер и начален адрес 0, което на практика ги обезсмисля). Това се налага поради факта, че при писането на приложни и системни програми сегментирането създава много главоболия и проблеми, а страницирането е напълно невидимо за потребителските програми.
 
Защитата на паметта от гледна точка на страницирането е доста "орязана": в описанието на страницата има само 2 еднобитови флага, които осигуряват следните нива на достъп: забранен всякакъв достъп, разрешено четене и разрешено четене и запис. В по-съвременните x86 процесори (произведени след 2003 г.) е въведен т. нар. [[NX бит]], който показва дали е разрешено изпълнението на програмен код в съответната страница. Това повишава сигурността на операционната система, предотвратявайки една от най-често използваните хакерски атаки - препълването на буфер.
 
=== Входно-изходно адресно пространство ===
==== Инструкции за трансфер на данни ====
 
* '''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''' - проверка на сегмент за право на четене и четене/запис.
 
== Проблеми ==