Теорія операційної системи

:: Меню ::

Головна
Представлення даних в обчислювальних системах
Машинні мови
Завантаження програм
Управління оперативною пам'яттю
Сегментна і сторінкова віртуальна пам'ять
Комп'ютер і зовнішні події
Паралелізм з точки зору програміста
Реалізація багатозадачності на однопроцесорних комп'ютерах  
Зовнішні пристрої
Драйвери зовнішніх пристроїв
Файлові системи
Безпека
Огляд архітектури сучасних ОС

:: Друзі ::

Карта сайту
 

:: Статистика ::

 

 

 

 

 

Регістри

Процесор сполучений з банками пам'яті шиною, по якій за один раз передається лише одне ціле число. Інколи розрядність цієї шини теж називають розрядністю процесора. Тоді 16-розрядний i8088 виявляється 8-розрядним, 32-розрядні Mc68000 і 180386sx -- 16-розрядними, а молодші моделі сучасних 64-розрядних RISC-процессоров — 32-розрядними. Для розробників апаратури така класифікація має сенс, а розробників програмного забезпечення вона може ввести в оману.
Арифметико-логічний пристрій процесора зазвичай не може оперувати даними, безпосередньо размешеннимі в оперативній пам'яті: для виконання арифметичної операції потрібний доступ одночасно до трьох елементів пам'яті, що зберігають операнди і результат.
Для вирішення цієї проблеми будь-який процесор має один або декілька регістрів — спеціалізованих пристроїв, що запам'ятовують, зазвичай вміщають ціле число або адресу. Всі процесори мають як мінімум шість регістрів — регістр для адреси поточної команди (лічильник команд), регістр прапорів, де зберігаються коди арифметичних умов і, крім того, багато іншої службової інформації (часто цей регістр називають словом достатку процесора), три буферні регістри АЛУ і буферний регістр, в якому зберігається поточна команда (мал. 2.1).

Мал. 2.1. Типова структура мікропроцесора

З цих регістрів програмістові доступні лише лічильник команд і слово достатку процесора, да і то не завжди. (Під доступністю програмістові в даному випадку ми маємо на увазі можливість вказувати регістри як явні і неявні операнди команд).
Регістри, доступні програмістові для зберігання даних, називаються регістрами спільного призначення (мал. 2.2). Окрім них, процесор зазвичай має безліч інших регістрів. Деякі з них цікаві лише проектувальникам апаратури, з іншими — наприклад, регістрами диспетчера пам'яті — ми ще зустрінемося в наступних главах.
Для доступу до регістрів процесору не потрібно займати зовнішню шину Даних, та і цикл доступу до регістра зазвичай дуже короткий і збігається з циклом роботи АЛУ. Отже, чим більше в процесора регістрів, тим швидше він може працювати з оперативними даними. В ті часи, коли комп'ютери були великими, прагнення до збільшення кількості регістрів упиралося у вартісні і електротехнічні обмеження. В комп'ютерів перших поколінь для реалізації регістрів використовувалися окремі транзистори або мікросхеми малої міри інтеграції, Тому вони коштували набагато дорожче (з розрахунку на один біт пам'яті), споживали значно більше енергії і розсіювали значно більше тепла, чим феритова пам'ять. Перехід на сучасні кристали високої інтеграції змінив положення, але не принципово: тригери, які використовуються для реалізації регістрів, по перерахованих параметрах завжди гірше, ніж виконане за тією ж технологією динамічне ОЗУ. Тому комп'ютери перших поколінь зазвичай мали лише декілька регістрів, а міні- і мікрокомп'ютери 70-х і почала 80-х минулого століття — не більше декількох десятків.

Мал. 2.2. Регістри спільного призначення в системі команд х86

В сучасних процесорів кількість регістрів вимірюється сотнями, а інколи і тисячами. Наприклад, замість буфера на одну лише поточну команду, всі без виключення сучасні процесори мають так звану чергу попередньої вибірки команд. В мікроконтроллерів PIC і Atmel те, що в специфікаціях вказано як ОЗУ (в молодших моделей 128 або 256 байт, а в старших — багато кілобайт), фактично є регістрами.

Регістрове вікно SPARC
RISC-процессор SPARC [www.sparc.com v9] має регістровий файл, об'єм якого в старих версій процесора складав 136 32-розрядних слів, а в сучасних 520 і більш. Цей файл складається з груп по 8 регістрів.
Програмі одночасно доступний 32 регістри, що нумеруються від 0 до 31, звані регістровим вікном. З них регістр 0 (що позначається як % g0) — виділений, читання з нього завжди повертає 0. Наступні 7 регістрів (що позначаються як %g1-%g7) використовуються для глобальних змінних. Ці регістри не входять в регістрове вікно. Регістри з r8 по r15 (%о0-%о7) використовуються для передачі параметрів процедурі (r15 використовується для зберігання адреси повернення підпрограми), що викликається, регістри з г24 по г31 (%i0-%i7) — для доступу до параметрів, і, нарешті, регістри з г16 по г23 (%I0-%I7) — для зберігання локальних змінних. При виклику підпрограми, команда save зрушує регістрове вікно, так що регістри %оО-%о7 зухвалої процедури стають регістрами %о0-%о7 процедури викликаної. Регістри rо-r7 зрушенням регістрового вікна не зачіпаються.
Таким чином, регістровий файл виконує функції стека викликів — в нім зберігаються адреси повернення, передаються параметри і зберігаються локальні змінні. Втім, такий підхід при всій його привабливості має великий недостаток— глибина стека викликів виявляється обмежена глибиною регістрового файлу. Спосіб усунення цього обмеження описаний в разд. Непрямий регістровий режим із зсувом.

Поважно ще раз відзначити, "що зазвичай далеко не всі наявні регістри безпосередньо доступні програмі. Так, в системі команд х86 передбачено всього вісім регістрів спільного призначення, але сучасні суперскалярні реалізації цієї архітектури (Pentium II, Athlon і т. д.) мають більше сотні фізичних регістрів і декілька арифметико-логічних пристроїв. Логіка попередньої вибірки дешифрує декілька команд і призначає виконання цих команд на вільні АЛУ, у міру їх вступу, з використанням вільних копій регістрів, при цьому, не порушуючи зв'язку за даними між послідовними командами.
За наявності великої кількості регістрів існує два підходи до їх вибору. Перший полягає в тому, що кожен код операції працює лише з
СВОЇМ регістром. Команда move %eax, %ebx — це одна команда, а move
%еах, %esp — зовсім інша. При цьому буває і так, що деякі команди Для деяких регістрів не визначені.
Другий підхід, симпатичніший авторові, називається ортогональною системою команд і полягає в тому, що всі команди (або хоч би більшість) можуть працювати з будь-якими регістрами. Номер регістра при цьому кодується спеціальним бітовим полем в коді команди (або декількома бітовими полями, якщо команда оперує декількома регістрами) (мал. 2.3).

Мал. 2.3. Формат команди мікропроцесора SPARC (цит. по [www.sparc.com v9])

При всіх недоліках першого підходу, ортогональна система команд створює специфічну проблему: збільшення кількості регістрів виявляється неможливим. Адже це вимагає розширення бітового поля номера регістра, а зміна розміру бітових полів команд - це порушення бінарної сумісності. Втім, в разд. Витісняюча багатозадачність ми зрозуміємо, чому навіть в неортогональних системах команд розширення номенклатури регістрів практично неможливе.


:: Реклама ::

 

:: Посилання ::


 

 

 


Copyright © Kivik, 2017