Последната актуализация на този раздел е от 2020 година.

 

6.4.4  Особености на командния цикъл в условия на виртуална памет

 

 

      Ние разгледахме по вертикала запомнящата система и всички структурни елементи, съдържащи се в съответните точки, както и алгоритмите, с които те се управляват. Може да твърдим, че системата от буферните (кеш) памети отделя процесора от оперативната памет и той няма непосредствен достъп до последната. Дори в случаите когато исканата информация не се съдържа в нито едно ниво на кеш системата и следва тя да се достави от оперативната памет, това е задача с която се справят хардуерно реализираните кеш-контролери. Но колкото и да се стараят механизмите на буферната памет да задоволят необходимостта на процесора от непосредствен достъп до информацията, съществуват ситуации, когато тя не се намира дори в оперативната памет. За съжаление “ръцете” на споменатите механизми не са достатъчно “дълги” за да достигнат до информацията, когато тя се намира във външната памет (на твърдия диск например). Вече пояснихме, че външната памет, като поредно ниво в йерархията на запомнящата система, е обединена в едно с оперативната памет под общо управление въз основа на понятието виртуална памет. Процесите по трансфер на информация между тези две нива на запомнящата система са многократно по-сложни и те не са по силите на кеш-контролерите. Както вече беше споменато в предидущите пунктове, във всички случаи, когато кеш-контролерите не са в състояние да осигурят заявените данни, същите генерират прекъсване (вижте поясненията в пункт 6.4.1). В отговор се задействат програмно реализирани механизми за трансфер на данни между външната памет и оперативната памет.

      Съществуват две различни ситуации, в които се стартират тези програмни механизми – при липса на машинна команда и при липса на заявен от команда операнд, или с други думи – на границата между две команди или по време на изпълнение на текущата команда. Прекъсването в случая между две команди тук не представлява интерес, тъй като то се реализира като всички останали, така както бе описано в глава 5.

      Във втория случай обаче ситуацията е съществено различна. Различна я прави фактът, че текущата команда, не успявайки да завърши нормално всички свои фази, се проваля и свързаният с нея адрес за връщане, става невалиден. Ситуациите са илюстрирани на следващата фигура 6.4.4.1.

 

Фиг. 6.4.4.1.  Прекъсване между две команди (отляво) и в команда (отдясно)

 

      Както се вижда в схемата отляво, адресът за връщане (a+L) е нормално формираният следващ адрес. Този адрес се получава автоматично в програмния брояч, където към адреса a на текущата команда е прибавена нейната дължина L в адресируеми единици. В схемата отдясно, където изобразеното прекъсване е по време на изпълнение на текущата команда, нормално формираният следващ адрес (a+L) не може да бъде адрес за връщане. Вероятно читателят разбира, че с незавършило действие, т.е. без резултат и без признаци на резултата, продължението на изчислителния процес не е редно. Ето защо незавършилата своето изпълнение команда №k отново трябва да получи шанс и нейната микропрограма трябва да се изпълни нормално до край. Грешка при обръщение към паметта може да настъпи по време на изпълнение на микропрограмата на машинната команда във фазата на извличане на операндите, или във фазата на запис на резултатите в паметта. Описаната проблематика се нарича проблем на точното прекъсване и беше подробно анализирана в пункт 5.4.5 във връзка на конвейерната организация на изпълнението на машинните команди.

      След обработване на прекъсването, управлението се връща на потребителската програма, която е била прекъсната с незавършила текуща команда, поради което нейното продължение е невъзможно по традиционният начин.

      За възстановяване хода на прекъснатата потребителска програма в тези случаи се прилагат два метода:

1.         Метод на повторението на провалилата се команда (рестарт на командата) ;

2.         Метод на продължението на провалилата се команда.

А)  Метод на повторението (рестарт)

      За да обясним случващото се, изходихме от условията на виртуалната памет, но в подобна ситуация машинната команда може да изпадне и по други причини. Тези причини, за разлика от обикновените прекъсвания, е прието да се наричат изключения, или още особени ситуации. Така например за своите процесори фирмата Intel дефинира следните две групи изключения:

1)       Грешки, капани и повреди ;

2)       Прекъсвания по време на изпълнението на командите:

- INT 0 – командата извиква процедура за обслужване на прекъсване при препълване ;

- INT 3 – командата извиква процедура за обслужване на прекъсване (контролна точка) ;

- INT n – командата извиква процедура за обслужване на прекъсване с номер n ;

- BOUND – команда за проверка дали индексът на даден масив не излиза извън декларираните за него граници. Ако границите са нарушени, се генерира код за прекъсване 5, адресът на програмния брояч при излизане от което сочи същата команда BOUND .

      Изключенията от първата група се определят по-подробно както следва:

1.       Грешки (faults). Грешките се откриват и обслужват непосредствено преди следващата команда. Най-често се явяват в системата на виртуалната памет, когато е заявен адрес към несъществуваща страница или сегмент. Съобщението подготвя процесора за рестарт на командата, генерирала грешката, т.е. адресът за връщане от обслужване на прекъсването представлява старото съдържание на програмния брояч. В същото време операционната система търси нужната страница или сегмент.

2.       Капани (traps). Съобщението за капан, в който е попаднал хода на изчислителния процес, се генерира непосредствено в края на текущата и преди следващата команда. Капаните това са контролни точки, които могат да бъдат залагани умишлено от потребителя, с цел контрол на изчислителния процес, обикновено при тестване на софтуера, чрез вмъкване в кода на програмата на еднобайтова команда INT 3.

3.       Повреди (аварийни прекъсвания) (aborts). При такива ситуации не винаги се разполага с адреса на командата, по време на която е настъпило изключението. По тази причина не винаги е възможен рестарт на командата и следователно на хода на изчислителния процес. Типични изключения от този вид са различни апаратни грешки, откривани от контролиращи логически схеми, или при противоречиви (недопустими) стойности в системните таблици.

      Заявките за обработка на изключенията се генерират от вътрешните схеми на процесора. В рамките на една команда могат да съществуват причини за няколко изключения, но в даден момент ще възниква само едно изключение. Процесорът ще обработва възникващите изключения последователно и ще рестартира машинната команда до нейното пълно изпълнение. Читателят навярно вече е разбрал, че процесорите на фирмата Intel, се придържат към метода на повторението. Редът, в който се проверяват възникналите изключения е следният:

1.       Проверка за капан след току що завършилата команда (постъпков режим – трасировка, или прекъсване по стойност на резултата) ;

2.       Проверка за грешки на следващата команда, според съдържанието в регистрите за трасиране на изпълнението DRn (n=0¸7) ;

3.       Проверка за наличие на заявки за външни прекъсвания ;

4.       Проверка за грешка при липса на сегмент ;

5.       Проверка за грешка при липса на страница ;

6.       Проверка за грешка при дешифриране на командата ;

7.       Проверка за наличие на FPU ;

8.       Проверка за грешки при операции в FPU, ако проверката е включена.

      Без да изпадаме в подробностите на процесорите Pentium тук ще споменем, че осъществяването на прекъсване е микропрограмна функция на командния цикъл, която пояснихме в 5-та глава. Споменатите по-горе изключения се обработват с помощта специални дескриптори (даннови структури), наречени “шлюзове”.

      Към изключенията от втората група, реализиращи се от съответните машинни команди, могат да се добавят многобройни допълнителни пояснения, свързани с конкретния процесор и конкретната машинна команда, което ние тук няма да направим, тъй като се придържаме единствено към задачата да изясним принципно проблема.

      Цялата информация за управление на едно задание от страна на операционната система се съдържа в даннова структура, която се нарича сегмент на състоянието на заданието TSS (Task State Segment). По същество в тази структура се съхранява цялата регистрова информация на процесора, необходима за идентификация и за стартиране на едно задание. Сегментът TSS има обем минимум 104[B], както показва следващата рисунка:

 

31                                            16

15                                              0

 

Базова карта на В/И адреси

Т

100

 

Сегментен селектор на  LDT

96

 

GS

92

 

FS

88

 

DS

84

 

SS

80

 

CS

76

 

ES

72

EDI

68

ESI

64

EBP

60

ESP

56

EBX

52

EDX

48

ECX

44

EAX

40

EFLAGS

36

EIP

32

CR3  (PDRB)

28

 

SS2

24

ES2

20

 

SS1

16

ESP1

12

 

SS0

8

ESP0

4

 

Селектор за връщане

0

Фиг. 6.4.4.2.  Формат на TSS

 

      Най-важното, което следва да поясним, тъй като ни касае в момента е, че в TSS се съдържа съдържанието на регистрите CS (Code Segment) и EIP (Expand Instruction Pointer). Двойката (CS:EIP) съответства на програмния брояч и определя адреса на машинната команда, която ще се рестартира. Изключенията, които възникват при обръщения към сегмент или към страница, се обработват различно от обикновените прекъсвания. В тези случаи най-напред се възстановява съдържанието на всички регистри на процесора в състоянието, в което са били преди интерпретацията на командата, предизвикала изключението. Ако приемем, че програмния брояч показва винаги следващия адрес, то текущия се получава лесно, като от него се извади дължината на текущата команда. Така, когато в последствие в стековата структура се съхранява съдържанието на програмния брояч, по същество ще бъде запомнен адресът на текущата команда, а не следващия по ред. Това е условието, което осигурява на операционната система възможността за рестарт на командата при възстановяване на приложението, т.е. при връщане от прекъсване.

      Според метода на повторението, който разглеждаме в момента, потребителската програма се стартира от незавършилата команда, т.е. нейната микропрограма се изпълнява от начало. За целта, съдържанието на програмния брояч, съдържанието на регистъра на състоянието и на останалите регистри с общо предназначение, трябва да бъде възстановено в структурата на процесора във вида до изпълнението на командата. Тази информация се извлича от споменатия вече TSS-сегмент. Така генералното решение на проблема е използуване на регистрово копие на състоянието на процесора. За да изпълнява ролята си, регистровото копие трябва да се обновява само след фактическо завършване на изпълнението на машинната команда, преди затваряне на командния цикъл.

      Тъй като в тази глава многократно се говореше за механизмите на предварителното извличане на машинни команди, следва да поясним съдържанието на програмния брояч допълнително. Разширеният указател на командата (EIP) съдържа изместването в текущия сегмент на кода, на следващата подлежаща на изпълнение команда (в линеен участък на програмата). Този указател не е достъпен за програмиста, но чрез своето съдържание, което се определя по силата на естествения метод на адресиране, от командите за преход, както и от прекъсванията, той управлява явно хода на програмата. Съдържанието на EIP се увеличава така, че винаги показва границата между изпълнените и неизпълнените машинни команди. Последните обаче се извличат предварително (изпреварващо във времето, т.е. относно споменатата граница). На етапа на предварителния анализ, за процесорите Pentium се осигурява изравнен 128 битов блок от кода, командите в който се съхраняват в очакване на изпълнение. Изравняването на блока, което също вече пояснихме, се осигурява чрез игнориране на младшите 4 бита от подаваните адреси. Блоковият трансфер игнорира границите между командите, тъй като върху системната шина той не ги различава като такива. По този начин, към началото на изпълнението на всяка команда, същата е отдавна заредена и декодирана. При изпълнение на команда за преход или извикване на подпрограма, процесорът зарежда изравнен блок, съдържащ адреса за преход или адреса на подпрограмата. При това, командите, които са били предварително заредени и декодирани, се отменят. Ако в резултат на предварителното зареждане се генерира изключение (например при излизане извън рамките на кодовия сегмент), това изключение не генерира прекъсване, докато се изпълняват команди, предшестващи байта, генерирал изключението. Ако пък командата се отменя, изключението не се генерира въобще.

      В реален режим на адресиране предварителното извличане може да доведе до обръщение от страна на процесора към неочакван за програмиста адрес. При работа в защитен режим (виртуална памет) изключението при обръщение към този адрес се обработват правилно. В реален режим обаче в този случай не съществува механизъм за правилно обръщение. Например, това е случай, когато системата не връща сигнал RDY# (сигнал, с който завършва цикъла на шината). Ето защо предварителното извличане следва да бъде защитено от цикли на шината при обръщение към несъществуващ (физически) адрес.

Б)  Метод на продължението

      При този метод след обслужване на прекъсването, управлението се връща в прекъснатата машинна команда, която продължава изпълнението си според своята микропрограма. С други думи, методът на продължението изисква да се изпълнява прекъсване, както на програмно, така и на миропрограмно ниво. Изпълнението на това прекъсване изисква запомняне както на регистровото съдържание на процесора, така и на съдържанието на служебните регистри. Типични представители на процесори, използващи метода на продължението, са тези на фирма Motorola.

      За да не изпадаме в излишни подробности, ще обобщим типичните за тези процесори изключения. Изключението тук е определено по същия начин, а всички изключения са групирани в 5 групи. Между изключенията е въведен приоритет. Редът на обработката им се определя от това кои изключения са разрешени и от реда в който са регистрирани, при едновременно възникване на условията за тях. Така например, ако възникне изключение грешка по шината и в същото време се изпълнява команда TRAP, тъй като грешката по шината има по-висок приоритет, изпълнението на команда TRAP ще бъде прекъснато. И още един пример, ако възникне заявка за прекъсване по време на изпълнението на поредната команда, при вдигнат флаг за трасировка Т, тъй като трасирането е с по-висок приоритет, то заявката за прекъсване ще бъде поставена в условие на изчакване. В таблицата по-долу са представени изключенията и техният приоритет.

Таблица 6.4.4.1  Изключения и приоритети

Група

Изключение

Обработка

0

Външен рестарт

Прекратява се изпълнението на текущата команда

1

Грешка в адреса ;

Грешка по шината .

Изключението се обработва в промеждутъка на 2 шинни цикъла. В стека се съхранява вътрешното състояние на процесора .

2

Команди BKPT #n, CALLM, CHK, CHK2 ;

Команди на копроцесора, изискващи при своята работа, обработка на изключение ;

Нарушение на копроцесорния протокол ;

Команда  cpTRAPcc  ;

Деление на нула  ;

Команди RTE, RTM, TRAP #n, TRAPV .

Завършва изпълнението на текущата команда, като обработката на изключението е част от изпълнението на командата .

3

ILLEGAL  команди  ;

Нарушена привилегия ;

Команди на копроцесора, изискващи преди своето изпълнение, обработка на изключение .

Завършва изпълнението на текущата команда. Обработката на изключението започва до изпълнението на командата, която извиква обработката на изключението.

4

Команди на копроцесора, изискващи обработка на изключение, след своето изпълнение  ;

Трасиране  ;

Външни прекъсвания .

Завършва изпълнението на текущата команда. Обработката на изключението започва след изпълнение на командата, изискваща изключение.

 

      Основното правило, което се спазва тук е, че колкото по-нисък е приоритетът на изключението, толкова по-рано се изпълнява процедурата за обработка на това изключение. Например, ако едновременно очакват обработка изключенията капан, трасиране и прекъсване, първо ще бъде обработено изключението капан, след него изключението трасиране и на края ще бъде обработено прекъсването. Когато процесорът продължи изпълнението на командата, той първоначално се намира в програмата за обработка на прекъсването, която ще върне управлението на обработката на трасирането, която от своя страна ще върне управлението на обработката на изключението капан. Както читателят на вярно разбира, това типичната LIFO дисциплина. Това правило не се прилага върху изключението рестарт – това изключение се обработва винаги първо, не защото има най-висок приоритет, а по простата причина, че това изключение отстранява всички други изключения.

      При обработката на изключенията най-непостоянната част от текущото състояние на процесора се съхранява във горната част на стека на супервайзора. Този контекст е организиран във формат, който се нарича стеков фрейм на изключението (Exception Stack Frame) (стекова рамка на изключението). Различните модели процесори поддържат различни формати стекови рамки. Въпреки, че информацията в тях варира в зависимост от модела на процесорите или от типа на изключението, тя винаги отразява моментното съдържание на регистъра на състоянието и на програмния брояч, по време на случващото се изключение. При това, ако изключението “грешка по шината” например, възникне по време на изпълнението на командата, това предизвиква запис в стека на дълъг кадър на състоянието, а ако то възникне на границата на две команди – в стека се записва къс кадър на състоянието. Дефинирани са няколко формата на кадъра на стека:

·         кадър $0 с обем от 8[B] ;

·         кадър $1 с обем от 8[B] ;

·         кадър $2 с обем от 12[B] ;

·         кадър $9 с обем от 20[B] ;

·         кадър $А с обем от 32[B] ;

·         кадър $В с обем от 92[B] ;

      Стековата рамка на изключението (“грешка по шината” и “грешка в адреса”) е показана в следващата таблица:

 

15   14                                                                          2   1   0

Регистър на състоянието

Програмен брояч (старша половина)

Програмен брояч (младша половина)

    Формат      |                Изместване на вектора

Специална дума на състоянието

Сгрешен адрес  (старша половина)

Сгрешен адрес  (младша половина)

резервирано

Изходен буфер за данни

резервирано

Входен буфер за данни

резервирано

Входен буфер за команди

 

Номер на версията

 

 

Вътрешна информация

Фиг. 6.4.4.3.  Стековата рамка на изключението

 

      Процесорът винаги се намира в едно от следните 3 състояния:

1.       Нормално състояние. Към това състояние се отнася състоянието при команда STOP и състоянието loop mode при команда DBcc. И в двете състояния обръщения към паметта не се извършват ;

2.       Състояние на изключение. Изключение може да възникне вътрешно за командата по време на нейното изпълнение, или външно, по причини, несвързани с нея (прекъсване, грешка по шината, ресет) ;

3.       Състояние Halted state. В това състояние процесорът индицира катастрофални грешки, например 2 последователни грешки по шината. Това състояние не е еквивалентно на Stoped state.

      Изключението се обработва в следната последователност:

1.       Създава се регистрово копие на вътрешното състояние. Процесорът се превключва в състояние супервайзор (S:=1), трасировката се отменя (T:=0). Обновява се маската на приоритетите (Interrupt priority mask) ;

2.       Определя се номерът на вектора на изключението ;

3.       В програмния стек се съхранява съдържанието на регистъра на състоянието и съдържанието на програмния брояч. В повечето случаи съдържанието на програмния брояч съответства на следващия по ред адрес ;

4.       В програмния брояч се записва ново съдържание.

      Изключенията по време на изпълнение на командата, например при “грешка по шината”, се обработват като се започне с незабавно прекратяване на текущия шинен цикъл. В тези случаи стековата рамка е с най-голям обем, който позволява работа в условия на виртуална памет. Разположението на данните в стека на супервайзора е следното:

15   14        . . . . . . . . . .                                               2   1   0

| R/W | I/N |  Код на функция

Адрес на обръщението   (старша половина)

Адрес на обръщението   (младша половина)

РЕГИСТЪР  НА  КОМАНДАТА

РЕГИСТЪР  НА  СЪСТОЯНИЕТО

Програмен брояч   (старша половина)

Програмен брояч   (младша половина)

 - - - - - - - - - - - -

където:  R/W# – четене/запис ;  I/N# – команда/не е команда .

      Случва се съдържанието на програмния брояч да бъде разположен след 2 до 10 байта от адреса на командата, причинила грешката по шината при обръщение към паметта. Това се дължи на изпреварващото извличане на команди. Ако грешката настъпи в процеса на извличане на следващата команда, адресът в програмния брояч може да се намира недалеко от текущата команда, която може да бъде и команда за преход. Покрай обикновената информация процесорът прави вътрешно копие на командата, която се е изпълнявала по време на изключението, както и копие на адреса, по който в първия такт на цикъла е правено обръщението. Съхранява се също така специфична информация за вида на достъпа (R/W# – четене/запис), за работата на процесора (I/N# – обработка на команда или не) и изходния код на функциите за достъп в момента на грешката и съдържанието на вътрешния регистър, който е трябвало да участва в трансфера на данни. В зависимост от вида на кадъра в стека се записва, както беше казано по-горе, до 92 байта допълнителна информация. Адресът, при който е настъпила грешката се използва от операционната система за определяне на фрейма виртуална памет, който следва да се трансферира в оперативната памет. Цялата допълнителна информация отразява вътрешното състояние на процесора по време на грешката (изключението). При изпълнение на команда RTE, при връщане от обработката, тази информация се презарежда обратно, с цел продължение на провалилата се команда. След като командата RTE възстанови състоянието на процесора се стартира шинният цикъл, с който се довършва прекъснатата команда. Ако е бил нарушен цикъл от тип “Четене-Модификация-Запис”, се стартира повторно целият цикъл, независимо каква е била заявената операция в сгрешената команда. Така информацията в стека се използва от процедурата за обработка на изключението за определяне на реда и начина на самата обработка.

      В случай, че съхранената в стека информация се окаже недостатъчна, съществува алтернативен начин за обработка на изключението. Той използва специалната дума на състоянието, входния буфер за команди, входния буфер за данни и изходния буфер за данни (вижте по-горе формата на стека). Структурата на специалната дума на състоянието е съставена от показаните по-долу флагове.

 

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

RR

*

IF

DF

RM

HB

BY

RW

*

*

*

*

*

FC2

FC1

FC0

Фиг. 6.4.4.4.  Специална дума на състоянието

 

      Значението на флаговете е следното:

RR – флаг за стартиране на продължението; RR=0 по подразбиране; RR=1 – програмно стартиране  ;

IF – извличане на команда във входния буфер за команди ;

DF – извличане на данни във входния буфер за данни ;

RM – цикъл от тип “Четене-Модификация-Запис” ;

HB – предаване на старшия байт от изходния буфер за данни във входния буфер за данни ;

BY – флаг за по байтово предаване ;

RW – RW=0 – запис ;   RW=1 – четене ;

FC – код на функцията за достъп по време на прекъснатия цикъл ;

*  – резервирано .

      Алтернативния начин за обработка на изключението представлява програмно завършване на достъпа. Ако шинният цикъл е за четене, то данните по отказания адрес трябва да са записани в изображението на буфера за входни данни, буфера за входни команди или и двата буфера, което зависи от флаговете DF и IF.

      Изключението “грешка по адреса” възниква, когато процесорът се опитва да обърне операнд от формат дълга дума или към команда по нечетен адрес. При грешка в паметта този процесор получава сигнал по входа BERR (грешка по шината). Шинният цикъл се прекратява, прекратява се микропрограмата на командата и се започва обработка на изключението в последователност, която по-горе пояснихме. В стека се съхранява същата информация като при изключението “грешка по шината”. Това позволява привилегированата команда RTE, която се изпълнява в системен режим, да осъществи продължението на изпълнението на прекъснатата команда. Ако обаче флагът RR не е вдигнат, при повторение на шинния цикъл се използва адресът на грешката и възниква друго изключение грешка по адрес. Ето защо, преди продължението на командата потребителят е длъжен да бъде уверен в това, че в съдържанието на стека в регистрите, които използва, са внесени необходимите поправки. В допълнение към връщането от процедурата по обработка на изключението, командата RTE продължава изпълнението на отложената команда, възстановявайки нормалния режим на процесора след възстановяване съдържанието на временните регистри и управляващата информация, съхранена при възникване на изключението. За правилната работа на команда RTE стекът трябва да съдържа достоверни и достъпни данни. Това команда RTE проверява по два начина – чрез проверка на четвъртата дума, която съдържа формат и изместване на вектора от една страна (вижте по-горе фигура 6.4.4.3) и от друга страна, данните се проверяват за достъпност, когато процесорът започне четене на дълги формати данни.

 

 

 

Следващият раздел е:

 

6.4.5.  Виртуален или физически адрес?