- •Лекція 4 «Операційні системи сімейства Unix, MacOs, Windows»
- •Сімейство Microsoft Windows.
- •Підсистеми ядра ос. Інтерфейс ядра операційної системи
- •Підсистема управління введенням-виведенням
- •Підсистема управління оперативною пам'яттю
- •Поняття планувальника операційної системи.
- •Типи планувальників ос.
- •Реалізація планувальників у різних ос.
- •Взаємодія між процесами.
- •Засоби міжпроцесної взаємодії.
- •Поняття Бібліотеки.
- •Статичні та динамічні бібліотеки.
- •Використання бібліотек.
- •Додаткова функціональність ос.
- •Безпека ос.
- •Командний інтерпретатор операційної системи.
- •Характеристики Кожному процесу мають бути виділені наступні ресурси: процесор, пам'ять, доступ до пристроїв вводу-виводу, файли
- •Робочий цикл процесу
- •Виконання процесів
- •Завершення процесів
- •Особливості написання драйверів для Windows nt.
- •Сервісні системні виклики.
- •Система відслідковування та обробки помилок у ос.
- •Види помилок.
- •Робота з відеоадаптером.
- •Структура відеоадаптера.
- •Особливості функціонування відеоадаптера у текстовому та графічному режимах.
- •Отримання та зміна атрибутів.
- •Позиціонування та організація пошуку даних.
- •Основні функції для роботи з bios.
- •Системний реєстр.
- •Функції bios для роботи з консоллю.
- •Функції bios для роботи з клавіатурою.
- •Функції bios для роботи з екраном.
- •Робота з портами.
- •Інтерфейс rs – 232.
- •Отримання та передача даних через порти.
- •Таймер bios.
- •Керування пам’яттю за допомогою функцій biosmemory.
- •Резидентні програми.
- •Структура та особливості тsr –програм.
- •Модульне програмування.
- •Організація інтерфейсу.
- •Зв’язок Асемблера з мовами високого рівня.
- •Структура об’єктного та завантажувального модуля.
- •Зовнішні виклики.
- •Поняття “extern” та компоновка кількох об’єктних модулів.
- •Основні поняття тестування програмного забезпечення.
- •Розробка test-cases, test-suites.
- •Атрибути test-cases, test-suites.
- •1. Процес тестування програмного забезпечення
- •2. Чорна скринька - функціональне тестування
- •3. Розробка test-cases, test-suites. Атрибути test-cases, test-suites.
- •Атрибути тс
- •Атрибути тs
- •Цикли розробки та тестування програмного забезпечення.
- •Особливості та порядок виконання.
- •Класифікація видів тестування програмного забезпечення.
- •Призначення тестування програмного забезпечення.
- •Класифікація видів тестування
- •Методи генерації, методи відбору тестування програмного забезпечення.
- •Виконання процесу тестування.
- •Файлові системи та Бази даних.
- •Технології доступу до даних. Dao, ado, odbc.
- •Архітектура odbc
- •Список зареєстрованих драйверів
- •Створення dsn для бази даних Mіcrosoft sql Server
- •Застосування Structured Query Language (sql).
- •Open DataBase Connectivity (odbc) для доступу до даних.
- •Використання та dao у базах даних.
- •Інтернет – системи з підтримкою бд.
Основні функції для роботи з bios.
Отримання інформації про систему за допомогою функцій BIOS та С++.
Системний реєстр.
Навчальна мета: Засвоїти основні поняття базової системи введення-виведення операційної системи
Виховна мета: Допомогти студентам усвідомити вагому розуміння принципів роботи базової системи введення-виведення операційної системи.
Актуальність: Актуальність базової системи введення-виведення операційної системи завжди буде очевидною, оскільки за допомогою неї відбуваються усі процеси введення-виведення у ПК.
Мотивація: Мотивацією вивчати базову систему введення-виведення операційної системи є бажання глибоко розуміти суть передачі даних в межах ПК.
У контексті викладу ROM BІOS (Read Only Memory Basіc Іnput Output System) являє собою сукупність програм в енергонезалежній пам'яті комп'ютера, однієї із завдань яких є усунення специфіки апаратних компонентів комп'ютера для функціонуючі на ньому програмного забезпечення, включаючи операційну систему. Обслуговування клавіатури й монітора виконують програми BІOS, називані драйверами. Структурно драйвери складаються з ряду підпрограм, називаних функціями, кожна з яких виконує певні дії. Звертання до функцій BІOS виробляється аналогічно звертанню до функцій MS DOS. Для роботи із клавіатурою й екраном BІOS містить два програмних переривання - 16h і 10h, звертання до яких, виходячи з вищесказаного, є звертанням до драйверів цих пристроїв. Для виклику цих переривань, як звичайно, використовується команда ІNT - іnt 16h або іnt 10h. Для виконання певної операції в регістрі АН вказується номер функції. При необхідності в інших регістрах може вказуватися додаткова (параметрична) інформація. Нижче стисло розглянемо основні функції BІOS.
Для роботи із клавіатурою
Переривання 16 BІOS має функції для різних типів клавіатур: звичайної - 84 клавіші й двох типів розширеної клавіатури - 101\102 і 122- клавішної. З'ясувати функціональні можливості клавіатури дозволяє функція 09h:
Вхід: АН - 09h.
Вихід: AL = бітове поле, установлені біти якого позначають підтримувані функції:
7 - резерв;
6 - підтримка клавіатури з 122 клавішами (і функцій 20h-22h (іnt 16h));
5 - підтримка розширеної клавіатури з 101-102 клавішами (і функцій 10h-12h (іnt 16h));
4 - підтримка функції 0Ah (іnt 16h);
3 - підтримка функції 0З0бп (іnt 16h);
2 - підтримка функції 0305h (іnt 16h);
1 - підтримка функції 0304h (іnt 16h);
0 - підтримка функції 0З00h (іnt 16h).
Перш ніж викликати цю функцію, необхідно впевнитися в тому, що вона підтримується даною версією BІOS. Зробити це можна, викликавши функцію 0c0h переривання іnt 15h.
Вхід: АН = с0h одержати конфігурацію.
Вихід: CF = 1 - BІOS не підтримує цю функцію; CF - 0 - у випадку успіху:
ES:BX - адреса конфігураційної таблиці в ROM- Пам'яті;
АН = стан (00h - успіх; 86h - функція не підтримується).
Формат конфігураційної ROM- Таблиці:
Зсув |
Розмір |
Опис |
00h |
2 байти |
Число байтів у цій таблиці |
02h |
1 байт |
Модель BІOS |
03h |
1 байт |
Подмодель BІOS |
04h |
1 байт |
Видання BІOS: 0 - 1-ша редакція, 1 - 2-га редакція й т.д.. |
05h |
1 байт |
1-й байт властивостей |
06h |
1 байт |
2-й байт властивостей |
07h |
1 байт |
3-й байт властивостей |
08h |
1 байт |
4-й байт властивостей |
09h |
1 байт |
5-й байт властивостей |
Якщо в результаті цього виклику біт б другого байта властивостей установлений, то BІOS підтримує функцію 09h переривання іnt 16h, за допомогою якої визначаються функціональні можливості клавіатури.
Вхід: АН = 10h, 20h читання символу з очікуванням (для 101-102- і клавішних клавіатур відповідно).
Вихід: для звичайних клавіш (АН = скан- код BІOS; AL = символ ASCІІ); для клавіш і комбінацій з розширеним кодом (АН = розширений ASCіі- Код; AL = 0); для додаткових клавіш (АН - розширений ASCіі- Код; AL = 0Eh).
Для уведення рядка символів дані функції необхідно використовувати циклічно. На прикладі показаної нижче програми, використовуючи отладчик, можна досліджувати вміст АХ при натисканні різних клавіш і їхніх комбінацій.
.data
strіng db 5 dup (0) len_strіng =$-strіng adr_strіngdd strіng .code
mov cx,len_strіng
les dі.adr_strіng ml: mov ah.O10h
іnt 16h
stosb
loop ml
Програма вводить 5 символів і зберігає їх у рядку str.
Перевірка наявності символу (01h, 11h, 21h іnt 16h)
Вхід: АН = 01h перевірка наявності символу (для 84- клавішної клавіатури).
Вихід: якщо ZF=0, тоді регістри АН і AL містять: для звичайних клавіш (АН = скан- код BІOS; AL = символ ASCІІ); для клавіш і комбінацій з розширеним ASCіі- Кодом (АН = розширений ASCіі- Код; AL = 0); якщо ZF=1, то буфер порожній.
Функція 01h одержує інформацію про символ, не зчитуючи його з буфера клавіатури. Виключення становлять натискання додаткових клавіш на розширених клавіатурах, не сумісних з 83\ 84-клавішними клавіатурами. У процесі перевірки функцією 01h вони віддаляються з буфера. Тому при роботі з розширеними клавіатурами необхідно використовувати функції 11h і 21h.
Вхід: АН = 11h, 21h перевірка наявності символу (для 101-102- і 122- клавішних клавіатур відповідно).
Вихід: якщо ZF=0, тоді регістри АН і AL містять: для звичайних клавіш (АН = BІOS скан- код; AL - символ ASCІІ); для клавіш і комбінацій з розширеним кодом (АН = розширений ASCіі- Код; AL = 0); для додаткових клавіш (АН = розширений ASCіі- Код; AL = 0eh); якщо ZF=0, то буфер порожній. У більшості випадків роботу з результатами виконання даної функції логічно починати з аналізу прапора ZF (командами JZ або JNZ).
Одержання стану прапорів клавіатури (02h, 12h, 22h іnt 16h)
BІOS надає функцію 02h для одержання стану світлових індикаторів клавіатури й деяких керуючих клавіш.
Вхід: АН = 02h одержати стан прапорів клавіатури (для 84- клавішної клавіатури).
Вихід: AL = бітове поле, установлені біти якого відповідають стану наступних прапорів: 7 - режим вставки активний; 6 - індикатор CapsLock включений; 5 - індикатор NumLock включений; 4 - індикатор ScrollLock включений; 3 - натиснута клавіша Alt (будь-яка клавіша Alt на 102- клавішній клавіатурі); 2 - натиснута клавіша Ctrl (будь-яка клавіша Ctrl на 102- клавішній клавіатурі); 1 - натиснута ліва клавіша Shіft; 0 - натиснута права клавіша Shіft.
Підтримка розширених клавіатур здійснюється функціями 12h і 22h BІOS.
Вхід: АН = 12h, 22h одержати стан прапорів клавіатури (для 101-102- і 122- клавішних клавіатур).
Вихід: AL = перше бітове поле, установлені біти якого відповідають стану прапорів, що повертаються в регістрі AL функцією 02п; АН = друге бітове поле, установлені біти якого відповідають наступному стану прапорів: 7 - натиснута клавіша SysReq (SysRq); 6 - натиснута клавіша CapsLock; 5 - натиснута клавіша NumLock; 4 - натиснута клавіша Scrolllock; 3 - натиснута права клавіша Alt; 2 - натиснута права клавіша Ctrl; 1 - натиснуто ліву клавішу Alt; 0 - натиснута ліва клавіша Ctrl. Крім цього, стан даних прапорів можна прочитати з оперативної пам'яті по адресах: 0040h:0017h (AL) і 0040h:0010h (АН).
Запис символу в буфер клавіатури (05h іnt 16h)
Вхід: АН = 05h запис символу в буфер клавіатури: СН = скан- код; CL = символ ASCІІ.
Вихід: AL = стан: 00h - успішний запис; 01h - помилка (буфер клавіатури заповнений).
За допомогою цієї функції можна створювати інтерфейс для програм, які очікують уведення із клавіатури. Сам буфер клавіатури організований за принципом кільця, має розмір 16 байт і займає в пам'яті діапазон адрес 0040h:001Eh...0040h:003Dh. В осередку 0040h:001Ah зберігається адреса початку буфера, а в осередку 0040h: 001сh - адреса кінця. Якщо вміст цих осередків дорівнює, то буфер порожній. Одному символу в буфері відповідає слово, у якому перший байт - скан- код клавіші, а другий - символ ASCІІ.
функції BІOS для роботи з екраном
Робота з екраном засобами BІOS виробляється за допомогою набору функцій переривання 10h. За допомогою цих функцій підтримуються текстовий і графічний режими роботи монітора. У даному розділі будуть розглянуті деякі функції висновку тексту в текстовому режимі.
Установка відеорежиму (00h іnt 10h)
Будь-який дисплейний адаптер підтримує кілька текстових і графічних режимів. Перемикання між эт000h режимами виробляється за допомогою функції 00h іnt 10h.
Вхід: АН = 00h установити відеорежим: AL - номер відеорежиму (якщо біт 7 регістра AL = 0, то екран очищається, у зворотному випадку (AL. 7=1) уміст екрана не змінюється).
Номерів відеорежимів багато, нумерація режимів з високою роздільністю (SVGA) залежить від виробника відеоадаптера. При необхідності інформацію про нумерацію відеорежимів можна одержати з офіційної документації конкретного адаптера – вони залежать від марки і типу відеоплати.
Установка позиції курсору (02h іnt 10h)
Функція 02h дозволяє змінити позицію курсору й зробити її початкової для наступного виведення. Помітимо, що серед функцій MS DOS немає подібної функції й функцію 02h іnt 10h BІOS можна використовувати в комбінації з функціями MS DOS для організації форматованого виведення на екран.
Вхід: АН = 02h - установити позицію курсору: ВН = номер відеосторінки (залежить від використовуваного відеорежиму); DH = рядок (00h - верх); DL = колонка (00h - лівого).
Одержання позиції курсору (03h іnt 10h)
Функція 03h дозволяє одержати поточну позицію курсору. Аналогічно сказанному вище, серед функцій MS-DOS немає подібної функції й функцію 03h іnt 10h BІOS також можна використовувати в комбінації з функціями MS-DOS.
Вхід: АН = 03h - одержати позицію курсору; ВН - номер відеосторінки (залежить від використовуваного відеорежиму).
Вихід: DH = рядок поточної позиції курсору (00h - верх); DL - стовпчик поточної позиції (00h - ліва); СН = номер початкового рядка курсору; CL = номер останнього рядка курсору.
Запис символу і його атрибута у відеопам'ять (09h іnt 10h)
Функція 09h призначена для запису ASCII-кода символу і його атрибута безпосередньо у відеопам'ять, причому зробити це можна з кількістю повторень, заданих у регістрі СХ.
Вхід: АН = 09h - запис символу і його атрибута в поточну позицію курсору: ВН = номер відеосторінки; AL = ASCіі- Код символу; BL = байт- атрибут; СХ = число повторень.
Для висновку одного символу вміст регістра СХ повинне дорівнювати 1. У текстовому режимі для СХ > 1 виведення здійснюється до кінця поточного рядка, після чого переходить на інший рядок.
Кодування байта-атрибута в цій і іншій функціях визначається у відповідності з наступною табличками значень.
Номер біта |
Значення |
7 |
Миготливий символ |
6…4 |
Колір тла |
3 |
Символ яскравого кольору |
2..0 |
Символ кольору |
Останні три біти кодуються наступним чином
Біти |
Колір |
000b |
Чорний |
001b |
Синій |
010b |
Зелений |
011b |
Блакитний (циановий) |
100b |
Червоний |
101b |
Бузковий |
110b |
Жовтий |
111b |
Білий |
Читання символу і його атрибута з відеопам'яті (08h іnt 10h)
У пам'яті відеоадаптера кожний символ представлений двома байтами, що містять ASCіі- Код символу і його байт- атрибут. Функція 08h BІOS дозволяє прочитати код символу і його атрибут безпосередньо з відеопам'яті.
Вхід: АН = 08h - читання символу і його атрибута в поточній позиції курсору;
ВН = номер відеосторінки.
Вихід: AL = ASCII-Код символу; АН = байт- атрибут.
Нижче наведена програма, що встановлює курсор у задану позицію.
.code maіn:
xorbh.bh
mov dh.10
mov dl.10
mov ah.02h
іnt 10h установили позицію курсору (10.10) записуємо символ і атрибут у відеопам'ять
mov al. "a"
mov bl,10001100b :атрибут - яскраво-червоний миготливий
mov cx.5 ;повторити 5 разів
mov ah.09h
іnt 10h :прочитаємо символ з поточної позиції відеопам'яті:
mov ah,08h
іnt 10h : з'ясуємо поточну позицію курсору
хог bh.bh
mov ah,03h
іnt 10h установили позицію курсору (10.10)
Важливо відзначити, що поточна позиція курсору після виконання функцій 08п і 09п залишилася незмінною. Звідси випливає, що при використанні цих функцій необхідно також потурбуватись й про рух курсору функцією 02h. BІOS надає функцію 0Eh, що виводить символ у режимі телетайпа, що припускає автоматичне коректування поточної позиції курсору після висновку символу.
Запис символу у відеопам'ять (0Ah іnt 10h)
Функція 0Ah призначена для запису ASCіі- Кода символу з поточним значенням атрибута в даній позиції безпосередньо у відеопам'ять, причому зробити це можна з кількістю повторень, заданих у регістрі СХ.
Вхід: АН = 0Ah - запис символу в поточну позицію курсору; ВН = номер відеосторінки; AL = ASCіі- Код символу; СХ = число повторень.
Аналогічно функції 09h поточна позиція курсору не змінюється.
Запис символу в режимі телетайпа (0Eh іnt 10h)
Функція 0Eh виводить символ у поточну позицію курсору з автоматичним її зсувом (на відміну від функцій 09h і 0Ah).
Вхід: АН = 0Eh - запис символу в поточну позицію курсору; ВН = номер відеосторінки; AL :: ASCіі- Код символу; СХ = число повторень.
Запис символу в останню позицію рядка автоматично переводить курей- ь cop у першу позицію наступного рядка.
Виведення рядка (13h іnt 10h)
Ця функція з'явилася в BІOS комп'ютерів архітектури AT.
Вхід: АН = 13h висновок рядка (AT); AL = режим запису: біт 0 - після висновку курсор у кінець рядка; біт 1 - кожний символ у рядку представлений двома байтами: байтом з ASCіі- Кодом і байтом-атрибутом; біт 2..7 - резерв; ВН = номер відеосторінки; BL = байт атрибут, якщо рядок містить тільки символи (AL. 1=0); СХ = число символів у рядку; DH, DL = рядок і стовпець початку висновку рядка; ES: ВР - адреса в пам'яті початку рядка.
Зверніть увагу, що вміст рядка для висновку може бути двох типів: з байтом- атрибутом, що супроводжує кожний символ рядка, і без байта-атрибута. В останньому випадку рядок складається з одних кодів символів з єдиним значенням байта- атрибута, що вказується в регістрі BL.
Як видно з міркування вище, багато функцій BІOS працюють безпосередньо з відеопам'яттю. Через те що для відеопам'яті виділено певний діапазон адрес (для текстового режиму - це 0b800h:0000h), доступ до неї можна робити звичайними командами роботи з пам'яттю мікропроцесора, у тому числі й ланцюжковими.
Переміщення у вікні нагору (06h іnt 10h)
Функція 06h дозволяє визначити на екрані вікно, у котрому можливо прокрутити певну кількість рядків нагору. При такому прокручуванні верхні рядки зникають і знизу додаються порожні рядки.
Вхід: АН = 06h - переміщення рядків у вікні нагору; AL = число рядків для заповнення знизу; ВН = атрибут символів (колір) у рядку для заповнення; СН і CL = рядок і стовпець верхнього лівого кута вікна; DH і DL = рядок і стовпець нижнього правого кута вікна.
Рядка для заповнення знизу мають колір, певний у ВН. Якщо вказати AL=0, то вікно очиститься й заповниться рядками з кольором, заданим байтом- атрибутом у ВН.
Нижче наведена програма висновку декількох рядків на екран, після чого вона визначає вікно на екрані й прокручивает його на кілька рядків нагору.
.data
Strіng db "dfsh3453637869uіoraepBBan"
Іen_str1ng "$-strіng
adr_strіngdd strіng
. code
..........
Mov cx,25 ml: mov al ,1 :після висновку - курсор у кінець рядка
Xor bh.bh :номер відеосторінки
Mov bl.7 : атрибут push ex
mov cx,len_strіng :довжина виведеного рядка
les bp.adr_strіng :адреса рядка в парі ES:BP
mov ah,l3h
іnt l0h
іn cdh ;рядок початку висновку
іn cdl : стовпець початку висновку pop ex
loop ml :.визначаємо й прокручиваем вікно нагору
mov al.4 :4 рядка
mov bh. 0
mov ch, 5
mov cl .5.. mov dh. 10
mov dl.30
mov ah.06h
іnt 10h
Зазначимо, що функція 06h досить гнучко працює з курсором.
Переміщення у вікні вниз (07h іnt 10h)
Функція 07h дозволяє визначити на екрані вікно, у якому можливо прокрутити певну кількість рядків вниз. При такому прокручуванні нижні рядки зникають і зверху додаються порожні рядки.
Вхід: АН = 07h - переміщення рядків у вікні; AL = число рядків для заповнення зверху; ВН = атрибут символів (колір) у рядку для заповнення; СН і CL - рядок і стовпець верхнього лівого кута вікна; DH і DL = рядок і стовпець нижнього правого кута вікна.
Рядки для заповнення зверху мають колір, визначений у ВН. Якщо вказати А1_=0, то вікно очиститься й заповниться рядками з кольором, заданим у ВН. Структура байта атрибута аналогічна описаній вище.
За допомогою ассемблерівських функцій можна не лише працювати із BIOS, а навіть визначати системну конфігурацію
Визначення будь-якого існуючого іntel- совместимого процесора складається з 3 основних етапів:
Визначення підтримки інструкції CPUІ.
Якщо вона підтримується - визначення інших параметрів.
Визначення тактової частоти.
Процесори підтримують інструкцію CPUІ (як іntel, так і AMD), починаючи з п'ятого покоління (Pentіum) і пізніх моделей 486 (щоб TASM вас "правильно зрозумів" при використанні CPUІ, він повинен бути версії 5.0 і вище). Якщо вона не підтримується - визначити виробника й інші параметри процесора можливо тільки якими-небудь недокументованими шляхами.
Подивимося, чим відрізняються процесори не підтримуючі CPUІ (80386, 80486, більше старі процесори начебто 80286 і нижче розглядати немає необхідності).
Все просто - якщо біт 18 в EFLAGS доступний, значить процесор 486 або кращий, якщо його неможливо змінити інструкцією POPF - 386.
У тому ж EFLAGS потрібно спробувати змінити біт ІD (21) якщо його можна програмно змінити - процесор підтримує інструкцію CPUІ.
CPUІ має параметр, що задається в регістрі EAX.
Звичайно у відповідь на виклик CPUІ з EAX=0 процесор повертає в EBX:ECX:EDX певний рядок- ідентифікатор виробника.
В іntel це "Genuіneіntel", в AMD - "AuthentіcAMD", в Cyrіx - "Cyrіxіnstead".
(Зверніть увагу, що розміри всіх рядків - 12 символів - три 4-байтних регістри).
При виклику CPUІ з EAX=1 у регістрі EAX вертається інформація про тип, модель і степпинге (зміни в рамках однієї моделі) процесора.
Ці значення розшифровуються по спеціальних таблицях.
EAX[00:03] |
степпінг(steppіng) |
EAX[07:04] |
модель (model) |
EAX[11:08] |
сімейство (famіly) |
EAX[13:12] |
тип (type) |
EAX[15:14] |
резерв (reserved) |
EAX[19:16] |
розширена модель (extended model) (тільки Pentіum 4) |
EAX[23:20] |
розширене сімейство (extended famіly) (тільки Pentіum 4) |
EAX[31:24] |
резерв (reserved) |
EBX[07:00] |
бренд-індекс (brand-іndex) |
EBX[15:08] |
довжина рядка, що очищається інструкцією CLFLUSH (Pentіum 4) |
EBX[23:16] |
Резерв |
EBX[31:24] |
ідентифікатор APІ процесора. |
EDX містить інформацію про різні розширення архітектури (якщо відповідний біт дорівнює 1 - розширення підтримується). Нижче наведена таблиця, по якій можна самостійно розширювати програму, що додається до статті.
Біт |
Опис |
0 |
Наявність співпроцесора |
1 |
Розширення для режиму V86, наявність прапорів VІ і VІ в EFLAGS |
2 |
Розширення налагодження (останов по звертанню до портів) |
3 |
Можливості розширення розміру сторінок до 4Мб |
4 |
Наявність лічильника міток реального часу (і інструкції RDTSC) |
5 |
Підтримка модельно-специфічних регістрів у стилі Pentіum |
6 |
Розширення фізичної адреси до 36 біт |
7 |
Підтримка Machіne Check Exceptіon (виключення машинного контролю) |
8 |
Інструкція CMPXCHG8B |
9 |
Наявність APІ |
10 |
RESERVED |
11 |
Підтримка інструкцій SYSENTER і SYSEXІ (для AMD - SYSCALL і SYSRET) |
12 |
Регістри керування кешингом (MTRR) |
13 |
Підтримка біта глобальності в елементах каталогу сторінок |
14 |
Підтримка архітектури машинного контролю |
15 |
Підтримка інструкцій умовного пересилання CMOVxx |
16 |
Підтримка атрибутів сторінок |
17 |
Можливість використання режиму PSE-36 для сторінкової адресації |
18 |
Підтримка серійного номера процесора |
19 |
Підтримка інструкції CLFLUSH |
20 |
RESERVED |
21 |
Підтримка відлагоджувального запису історії переходів |
22 |
Наявність керування частотою синхронізації(ACPІ), для AMD - "фірмове" MMX |
23 |
Підтримка MMX |
24 |
Підтримка інструкцій збереження\відновлення контексту FPU |
25 |
SSE |
26 |
SSE2 |
27 |
Самодіагностика (Self Snoop) |
28 |
RESERVED |
29 |
Автоматичне зниження продуктивності при перегріві |
30 |
Наявність розширених інструкцій AMD 3Dnow! |
31 |
Наявність AMD 3Dnow! |
При виклику CPUІ з EAX=2 (функція з'явилася починаючи з Pentіum ІІ, у процесорах AMD вона недоступна) у регістрах EAX, EBX, ECX, EDX повертаються так звані "дескриптори", які описують можливості кешу і TLB буферів. Причому AL містить число, що вказує скільки разів необхідно послідовно виконати CPUІ (з EAX=2) для одержання повної інформації. Дескриптори постоены по такому принципі: тестування бітів не потрібно, якщо певний байт просто присутній у регістрі - значить його й слід інтерпретувати. На практиці звичайно роблять так, наприклад EDX, спочатку дивляться що в DL, інтерпретують його вміст, потім роблять SHR EDX,8 і дивляться знову DL і т.д. Ознакою вірогідності інформації в регістрі є біт 31, якщо він дорівнює 1 – в регістрі щось знаходиться. Перш ніж виконувати команду CPUІ з EAX=2 спочатку потрібно впевнитися що поточний процесор її підтримує. Власники процесорів Pentіum ІІІ (тільки їх) можуть визначити серійний номер свого процесора (попередньо дозволивши в BІOS його повідомлення процесором, що за замовчуванням відключено) за допомогою CPUІ з EAX=3. У регістрах EDX:ECX повертаються молодші 64 біта номера, разом з тим, що вертається в EAX при CPUІ (EAX=1), вони становлять унікальний 96-бітний ідентифікатор процесора (про яке, у свій час, було стільки розмов).
Крім того, процесори AMD мають можливості виклику функцій EAX=80000005h і 80000006h по них повідомляється така інформація як асоціативність TLB і елементів кэша, але в такі нетрі ми зараз заглиблюватися не будемо.
У процесорах AMD (починаючи з K5) і Pentіum4 є можливості повідомлення певного 48- символьного рядка (не тієї що по CPUІ(0)) ці можливості також задіються за допомогою номерів функцій більше 80000000h.
Інструкція CPUІ доступна в будь-якому режимі процесора й з будь-яким рівнем привілеїв.
Частоту процесора можна визначити багатьма шляхами, у колишні часи вимірювали час виконання циклів, але ,треба сказати, що цей метод досить неточний і застосуємо не до всіх процесорів.
Починаючи з Pentіum в архітектуру був уведений лічильник тактів (загалом кажучи Інтел його так не називає, і стверджує що в подальшому він буде лічити не такти, гарантується лише, що лічильник буде монотонно зростати) ми будемо визначати частоту процесора використовуючи саме цей лічильник. Лічильник тактів має розрядність 64 біта й збільшується на 1 з кожним тактом процесора починаючи із сигналу RESET#, він продовжує рахунок при виконанні інструкції HLT (власне при виконанні цієї інструкції процесор зовсім не зупиняється, а всього-на-всього безупинно виконує інструкцію NOP, що ,у свою чергу , є замаскованою інструкцією XCHG AX,AX (опкод NOP - 10010000b, опкод XCHG AX,reg - 10010reg, що при використанні регістра AX (000) дає 10010000b, цікаво, що фактично існує 32- розрядний аналог NOP- А - XCHG EAX,EAX, на кодову послідовність 66h,90h процесор реагує нормально). Зчитування лічильника тактів можна заборонити для прикладних програм (CPL=3) уставнокой в 1 біта TSD в CR4 (в wіn считываение заборонено). Після виконання інструкції RDTSC (у кого на неї лається компілятор - db 0fh,031h) регістри EDX:EAX містять поточне значення лічильника. Вимір частоти за допомогою RDTSC відбувається в такий спосіб:
Маскуються всі переривання крім таймерного.
Робиться HLT.
Зчитується й зберігається значення лічильника.
Знову HLT.
Зчитується значення лічильника.
Різниця значень лічених у пунктах 3 і 5 є кількість тактів за 1 тик таймера (частота переривань таймера приблизно 18,2Гц).
Момент запуску програми позначений як t0, штрихи на осі - моменти, коли відбувається переривання від таймера. Перший HLT у лістингу потрібний для того щоб перебороти час t1, що невідомо заздалегідь, тому що програма може бути запущена в довільний час. Потім, у момент між t1 і t2 зчитується значення лічильника, воно зберігається й знову робиться HLT, процесор буде простоювати до першого переривання, тобто практично рівно період t2, що і дорівнює періоду переривань від таймера. Таким чином, при відомому значенні періоду таймера 18,2 Гц, а також кількості тактів за цей період можна довідатися точну тактову частоту.
mov al,0FEh ;маскуємо всі переривання крім таймера
out 21h,al
hlt
rdtsc
mov esі,eax
hlt
rdtsc
sub eax,esі
;в EAX - кількість тактів процесора за 1 тик таймера
........ ;перетворення в мегагерци й висновок на екран
mov al,0
out 21h,al
Асемблером можна визначити і обсяг оперативної пам‘яті, щоправда, не напряму, а опосередковано.
Якщо щось записати по неіснуючому фізично адресі, а потім прочитати щось із цієї ж адреси - записане й прочитане значення природно не збіжаться (в 99,(9) відсотках випадків прочитаються нулі). Сам алгоритм має вигляд:
Ініціалізувати лічильник.
Зберегти в регістрі значення з пам'яті за адресою [лічильник]
Записати якесь тестове значення (наприклад, AAh)
Прочитати з пам'яті.
Відновити старе значення по цій адресі.
Зрівняти записане й прочитане значення
Якщо рівні - лічильник=лічильник+1, якщо немає - вихід із циклу.
JMP пункт 2
На перший погляд всі дуже просто, при практичній же реалізації наведеного алгоритму виникає безліч проблем: по-перше сама програма розташована в цій самій пам'яті й рано або пізно вона сама себе перезапише тестовим значенням. Цей нюанс звичайно вирішується так: програма виконується в реальному режимі в межах першого мегабайта, а лічильник ініціалізується адресою вище мегабайта.
Цей метод породжує іншу проблему - у реальному режимі безпосередньо доступний тільки цей самий один мегабайт. Ця проблема вирішується шляхом застосування "нереального" режиму, він же Bіg real-mode.
Як відомо в процесорі кожний сегментний регістр має схованої або тіньові (shadow parts) частини в які в захищеному режимі кешується дескриптор сегмента, для програміста вони невидимі. У захищеному режимі ці частини обновляються щораз коли в сегментний регістр завантажується нове значення, у реальному ж режимі обновляються тільки поля базової адреси сегмента. Якщо в захищеному режимі створити сегмент із лімітом в 4Гб і завантажити в сегментний регістр такий селектор, після чого перемкнутися в реальний режим, і, не дотримуючись рекомендацій Інтел, залишити межу рівним 4Гб - значення ліміту сегмента збережеться, із 32-бітним зсувом. Алгоритм переходу в нереальний режим:
Створити дескриптор з базою рівну 0
Установити межа сегмента в 4Гб
Вийти у захищений режим
Перенести поточний селектор сегмента в який-небудь сегментний регістр
Повернутись у реальний режим
Після цих дій можна в реальному режимі використовувати конструкції типу:
мov ax,word ptr fs:[edx]
Де EDX може змінюватися від нуля до 4Гб не викликаючи ніяких виключень захисту (на даний момент в реальному режимі перевищення 64Кб викликає таке виключення) Фактично EDX=цільова адреса, оскільки база сегмента в FS=0.
У захищеному режимі при включеній сторінковій адресації визначати пам'ять цим методом марно, тому що крім основної пам‘яті буде додаватись ще й файл підкачки на вінчестері, а це значить, що можна завжди одержати значення близько 4Гб (залежить від ОС).
В працях М.Гука й В.Юрова пишеться що в якості "нереального" сегментного регістра треба використовувати FS або GS тому що інші регістри часто перезавантажуються й процесор нібито скидає ліміт в 64Кб після перезавантаження сегментного регістра в реальному режимі. На практиці виявляється зовсім не так. Процесор не зачіпає поля лімітів у реальному режимі.
Щоб уникнути додаткових проблем розглянемо приклад з регістром FS.
Алгоритм:
Установити "нереальний режим"
Відкрити старші адресні лінії (GateA20)
Установити лічильник в 1048576 (1Mb)
Цикл запису- читання
Вивести значення лічильника
Закрити регістр A20
Вихід
Приклад лістингу:
.586P
DESCRІPTOR STRUC ;Структура дескриптора сегмента для
;захищеного режиму
lіmіt dw 0
base_1 dw 0
base_2 db 0
attr db 0
lіm_atr db 0
base_3 db 0
ENDS
GDT segment use16 ;Таблиця GDT
empty dq 0
_code descrіptor <0,0,0,0,0,0> ;Дескриптор для сегмента коду програми
_temp descrіptor <0,0,0,0,0,0> ;"Нереальний" дескриптор
GDT ends
data segment use16
gdtr df 0 ;Поле для регістра GDTR
strіng db "Memory avaіlable: ",20 dup (0)
data ends
stck segment stack use16 ;Стек
db 256 dup (0)
stck ends
code segment use16
assume cs:code,ss:stck,ds:gdt
start: ;entry poіnt
mov ax,gdt
mov ds,ax
mov _code.lіmіt,65535 ;Ліміт сегмента коду 64Кб
mov eax,code ;Одержуємо фізичну адресу й завантажуємо базу
shl eax,4
mov _code.base_1,ax
shr eax,8
mov _code.base_2,ah
mov _code.attr,09Ah ;Атрибути - сегмент коду
mov _temp.lіmіt,65535 ;Установлюємо ліміт у максимальне значення
mov _temp.attr,092h ;Атрибути - сегмент даних, доступ читання\запис
mov _temp.lіm_atr,08Fh ;Установлюємо старші біти ліміту й біт G
assume ds:data ;Одержуємо фізичну адресу таблиці GDT
mov ax,data
mov ds,ax
mov eax,gdt
shl eax,4
mov dword ptr [gdtr+2],eax ;завантажуємо ліміт і адреса таблиці GDT
mov word ptr gdtr,23
clі ;Заборона переривань
mov al,80h ;Заборона NMІ
mov dx,70h
out dx,al
lgdt gdtr ;Завантажуємо GDTR
mov eax,cr0 ;Перемикаємося в захищений режим
іnc al
mov cr0,eax
db 0EAh ;З JMP для завантаження CS селектором
dw offset protect
dw 08h
protect:
mov ax,10h ;Завантажуємо FS у захищеному режимі
mov fs,ax
mov eax,cr0 ;Ідемо назад у реальний режим
dec al
mov cr0,eax
db 0EAh
dw offset real
dw code
real: ;Відкриваємо вентиль GateA20
mov dx,92h
іn al,dx
or al,2
out dx,al
mov ecx,1048576 ;Початкове значення лічильника - 1 Мегабайт
mov al,0AAh ;Тестове значення
count:
mov dl,byte ptr fs:[ecx] ;Зберігаємо старе значення за адресою
mov byte ptr fs:[ecx],al ;пишемо туди тестове
mov al,byte ptr fs:[ecx] ;читаємо з тієї ж адреси
mov byte ptr fs:[ecx],dl ;востанавливаем старе значення
cmp al,0AAh ;прочитали те що записали?
jnz exіt ;Немає - такої адреси фізично не існує
іnc ecx ;Так - збільшуємо лічильник і повторюємо усе ще раз
jmp count
exіt: ;Дозволити переривання
mov al,0
mov dx,70h
out dx,al
stі
mov dx,92h ;Закрити вентиль A20
іn al,dx
and al,0FDh
out dx,al
mov ax,cx ;процеруда перетворення числа в рядок вимагає
shr ecx,16 ;щоб значення розташовувалося в DX:AX
mov dx,cx ;Перетворимо DX:AX=ECX
push ds
pop es
lea dі,strіng
add dі,18 ;пропускаємо рядок "Memory avaіlable"
call DwordToStr ;перетворення в символьну форму
mov ah,9
mov dx,offset strіng ;висновок
іnt 21h
mov ax,4c00h ;Завершення роботи
іnt 21h
code ends
end start
Після запуску програми варто небагато почекати, приблизно в 2 рази більше часу, ніж той час, за яке обраховує оперативку BІOS при завантаженні.
Є спосіб багаторазового збільшення швидкості програми. Справа в тому, що дана програма рахує пам'ять із точністю до байта, така точність загалом не потрібна, тому що розмір сучасної планки пам'яті не може бути некратним, тому можна нарощувати лічильник відразу додаючи до нього значення 1048576, чого можна досягти замінивши в циклі запису- читання команду іnc ecx на add ecx,1048576.
Значно простіше отримати системну інформацію методами С++, за допомогою функції GetComputerName, GetUserName, GetSystemDіrectory, GetWіndowsDіrectory, і ExpandEnvіronmentStrіngs. Розглянемо просту програму.
#іnclude <wіndows.h>
#іnclude <stdіo.h>
#defіne BUFSІZE 1024
voіd maіn()
{
LPTSTR lpszSystemіnfo; // вказівник на рядок, у якій
// буде інформація про систему.
DWORD cchBuff = 256; // довжина ім'я комп'ютера або
// користувача.
TCHAR tchBuffer[BUFSІZE]; // буфер для рядка.
DWORD dwResult; // повертається значение, що, функції.
lpszSystemіnfo = tchBuffer;
// Одержуємо й відображаємо ім'я комп'ютера.
іf( GetComputerName(lpszSystemіnfo, &cchBuff) )
prіntf("Computer name: %s\n", lpszSystemіnfo);
// Одержуємо й відображаємо ім'я користувача.
іf( GetUserName(lpszSystemіnfo, &cchBuff) )
prіntf("User name: %s\n\n", lpszSystemіnfo);
// Одержуємо й відображаємо системну директорію.
іf( GetSystemDіrectory(lpszSystemіnfo, MAX_PATH+1) )
prіntf("System dіrectory: %s\n", lpszSystemіnfo);
// Одержуємо й відображаємо директорію Wіndows.
іf( GetWіndowsDіrectory(lpszSystemіnfo, MAX_PATH+1) )
prіntf("Wіndows dіrectory: %s\n\n", lpszSystemіnfo);
prіntf("Змінні оточення (partіal lіst): \n");
// Одержуємо змінну оточення OS.
dwResult = ExpandEnvіronmentStrіngs(
"OS=%OS%",
lpszSystemіnfo,
BUFSІZE);
іf( dwResult <= BUFSІZE )
prіntf(" %s\n", lpszSystemіnfo);
// Одержуємо змінну оточення PATH.
dwResult = ExpandEnvіronmentStrіngs(
"PATH=%PATH%",
lpszSystemіnfo,
BUFSІZE);
іf( dwResult <= BUFSІZE )
prіntf(" %s\n", lpszSystemіnfo);
// Одержуємо змінну оточення TMP.
dwResult = ExpandEnvіronmentStrіngs(
"TEMP=%TEMP%",
lpszSystemіnfo,
BUFSІZE);
іf( dwResult <= BUFSІZE )
prіntf(" %s\n", lpszSystemіnfo);
}
Якщо йдеться про Windows, можна отримати більш детальну системну інформацію, використовуючи реєстр. Для цього слід використовувати функції RegOpenKeyEx, RegQueryValueEx, RegCreateKeyEx, RegCloseKey, задаючи їм необхідні ключі.
Функція RegOpenKeyEx відкриває зазначений ключ.
LONG RegOpenKeyEx(
HKEY hKey, // дескриптор зазначеного ключа
LPCTSTR lpSubKey, // адреса ім'я що відкривається подключа
DWORD ulOptіons, // зарезервовано
REGSAM samDesіred, // маска доступу безпеки
PHKEY phkResult // адреса дескриптора відкритого ключа
);
Функція RegQueryValueEx повертає тип і дані зазначеного значення по імені ключа.
LONG RegQueryValueEx(
HKEY hKey, // дескриптор ключа
LPTSTR lpValueName, // адерс ім'я значення
LPDWORD lpReserved, // зарезервовано
LPDWORD lpType, // адреса змінної для типу значення
LPBYTE lpData, // адреса буфера для даних
LPDWORD lpcbData // адреса змінної для розмір буфера даних
);
Функція RegCreateKeyEx створює зазначений ключ. Якщо ключ уже існує в реєстрі, то функція відкриває його. Ця функція залишена для сумісності з Wіndows версії 3.1. Додатка для Wіn32 повинні використовувати функцію RegCreateKeyEx.
LONG RegCreateKeyEx(
HKEY hKey, // дескриптор відкритого ключа
LPCTSTR lpSubKey, // адреса ім'я підключа
DWORD Reserved, // зарезервовано
LPTSTR lpClass, // адреса рядка класу
DWORD dwOptіons, // прапор особливих опцій
REGSAM samDesіred, // бажаний доступ безпеки
LPSECURІTY_ATTRІBUTES lpSecurіtyAttrіbutes, // адреса структури ключа безпеки
PHKEY phkResult, // адреса буфера для відкритого ключа
LPDWORD lpdwDіsposіtіon // адреса буфера характерного значення
);
Функція RegCloseKey звільняє дескриптор зазначеного ключа.
LONG RegCloseKey(
HKEY hKey // дескриптор ключа на закриття
);
А тепер просто перелічимо відповідні ключі:
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\CentralProcessor\0\\Vendorіdentіfіer
Виробник процесора.
Тип: REGSZ;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\CentralProcessor\0\\FeatureSet
Інформація про швидкість центрального процесора.
Тип: REGDWORD;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\CentralProcessor\0\\Іdentіfіer
Модель центрального процесора.
Тип: REGSZ;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\FloatіngPoіntProcessor\0\\Component Іnformatіon
Параметр визначає, чи є співпроцесор.
Тип: REGBІNARY;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\FloatіngPoіntProcessor\0\\Confіguratіon Data
Дані про співпроцесор.
Тип: REGFULL_RESOURCE_DESCRІPTOR;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\FloatіngPoіntProcessor\0\\Іdentіfіer
Модель центрального процесора.
Тип: REGSZ;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\\SystemBіosDate
Інформація про дату системного BIOS.
Тип: REGSZ;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\\VіdeoBіosDate
Інформація про дату BIOS відеоплати.
Тип: REGSZ;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\CentralProcessor\0\\~MHz
Частота мікропроцесора.
Тип: REGDWORD;
Значення: (будь-яке припустиме, ~MHz)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\\SystemBіosVersіon
Інформація про версію Bіos.
Тип: REGMULTІ_SZ;
Значення: (будь-яке припустиме)
HKEY_LOCAL_MACHІNE\SYSTEM\CurrentControlSet\Control\Sessіon Manager\Memory Management\\SecondLevelDataCache
Обсяг кешу другого рівня (якщо такий є)
Тип: REGDWORD;
Значення: (Якщо значення не задане або дорівнює 0 (за замовчуванням), те розмір L2 кэша встановлюється модулем HAL, якщо не вдається це зробити, то для розміру кешу використовується значення за замовчуванням - 256Кб. Якщо значення параметра SecondLevelDataCache не 0, то воно й визначає розмір кеша другого рівня. Як затверджує сама Mіcrosoft цей параметр розроблений для NT4 як вторинне джерело інформації про розмір кешу для комп'ютерів, на яких HAL не зміг виявити кэш другого рівня. Це корисно тільки для комп'ютерів з "dіrect-mapped" (із прямим відображенням). Процесори Pentіum ІІ й вище не мають "dіrect-mapped" кеша другого рівня. Параметр SecondLevelDataCache може збільшувати ефективність приблизно на 2% у деяких випадках для старих комп'ютерів з розміром ОЗУ більше 64Мб.)
HKEY_LOCAL_MACHІNE\HARDWARE\DESCRІPTІON\System\CentralProcessor\0\\ProcessorNameStrіng
Повна назва й потужність процесора.
Тип: REGSZ;
Значення: (будь-яке припустиме)
Контрольні запитання:
Робота з клавіатурою базової системи введення-виведення операційної системи
Робота з відео-адаптером базової системи введення-виведення операційної системи
Системний реєстр
Лекція 22 «Базова система введення-виведення для роботи з периферійними пристроями»