Автор: Пользователь скрыл имя, 20 Ноября 2012 в 22:41, курсовая работа
Сучасні відкриті операційні системи, такі як Linux або OPENBSD походять від операційної системи UNIX, що з’явилася на початку 1970-х років і зробила величезний вплив на практичні реалізації операційних систем і розвиток всієї області інформаційних технологій. Тому вивчення будь-якою з сучасних UNIX-подібних операційних систем неможливо без розгляду основних ідей, закладених в оригінальний UNIX.
Сегменти
Сегментом називається область, яка починається на межі параграфа,
тобто за будь-якою адресою, яка ділиться на 16 без залишку. Хоча сегмент може розташовуватися в будь-якому місці пам’яті і мати розмір до 64 Кбайт, він вимагає стільки пам’яті, скільки необхідне для виконання програми. Є три головні сегменти:
1) сегмент кодів. Сегмент кодів містить машинні команди, які виконуватимуться. Звичайно перша виконувана команда знаходиться на початку цього сегменту і операційна система передає управління за адресою даного сегменту для виконання програми. Регістр сегменту кодів (CS) адресує даний сегмент;
2) сегмент даних. Сегмент даних містить певні дані, константи і робочі області, необхідні програмі. Регістр сегменту даних (DS) адресує даний сегмент;
3) сегмент стека. Стек містить адреси повернення як для програми для повернення в операційну систему, так і для викликів підпрограм для повернення в головну програму. Регістр сегменту стека (SS) адресує даний сегмент.
Ще один сегментний регістр, регістр додаткового сегменту (ES), призначений для спеціального використання. Три сегментні регістри містять початкові адреси відповідних сегментів і кожен сегмент починається на межі параграфа.
Усередині програми всі адреси пам’яті відносні до початку сегменту. Такі адреси називаються зсувом від початку сегменту. Двобайтовий зсув (16-біт) може бути в межах від 000016 до FFFF16 або від 010 до 6553510. Для звернення до будь-якої адреси в програмі, комп’ютер складає адресу в регістрі сегменту і зсув. Наприклад, перший байт в сегменті кодів має зсув 0, другий байт – 01, і так далі до зсуву 65535.
Регістри
Процесори 8086/8088 мають 14 регістрів, які використовуються для управління програмою, що виконується, для адресації пам’яті і для забезпечення арифметичних обчислень. Кожен регістр має довжину в одне слово (16 біт) і адресується по імені. Біти регістра прийнято нумерувати зліва направо:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Процесори 80286 і 80386 мають ряд додаткових регістрів, деякі з них 16-бітові. Ці регістри тут не розглядаються.
Сегментні регістри CS, DS, SS і ES
Кожен сегментний регістр забезпечує адресацію 64Кб пам’яті, яка називається поточним сегментом. Як показано раніше, сегмент вирівнюється на межу параграфа і його адресу в сегментному регістрі припускає наявність справа чотирьох нульових бітів.
1) регістр CS. Регістр сегменту коду містить початкову адресу сегменту коду. Ця адреса плюс величина зсуву в командному покажчику (IP) визначає адресу команди, яка повинна бути вибрана для виконання. Для звичайних програм немає необхідності робити посилання на регістр CS;
2) регістр DS. Регістр сегменту даних містить початкову адресу сегменту даних. Ця адреса плюс величина зсуву, визначена в команді, указують на конкретний осередок в сегменті даних;
3) регістр SS. Регістр сегменту стека містить початкову адресу в сегменті стека;
4) регістр ES. Деякі операції над рядками використовують додатковий сегментний регістр для управління адреси цієї пам’яті. У даному контексті регістр ES пов’язаний з індексним регістром DI. Якщо необхідно використовувати регістр ES, асемблерна програма повинна його ініціалізувати.
Регістри загального призначення: AX, BX, CX і DX
При програмуванні на асемблері регістри загального призначення є «робочими конячками». Особливість цих регістрів полягає в тому, що можлива адресація їх як одного цілого слова або як однобайтової частини. Лівий байт є старшою частиною (high), а правий – молодшою частиною (low). Наприклад, двобайтовий регістр CX складається з двох однобайтових: CH і CL, і посилання на регістр можливі по будь-якому з цих трьох імен.
1) регістр AX. Регістр AX є основним суматором і застосовується для всіх операцій введення-виведення, деяких операцій над рядками і деяких арифметичних операцій. Наприклад, команди множення, ділення і зсуву припускають використання регістра AX. Деякі команди генерують ефективніший код, якщо вони мають посилання на регістр AX;
AX: | AH | AL |
2) регістр BX. Регістр BX є базовим регістром. Це єдиний регістр загального призначення, який може використовуватися як «індекс» для розширеної адресації. Інше загальне застосування його – обчислення;
BX: | BH | BL |
3) регістр CX. Регістр CX є лічильником. Він необхідний для управління числом повторень циклів і для операцій зсуву вліво або вправо. Регістр CX використовується також для обчислень;
CX: | CH | CL |
4) регістр DX. Регістр DX є регістром даних. Він застосовується для деяких операцій введення/виведення і тих операцій множення і ділення над великими числами, які використовують регістрову пару DX і AX;
DX: | DH | DL |
Будь-які регістри загального призначення можуть використовуватися для складання і віднімання як 8-ми, так і 16-ти бітових значень.
Регістрові покажчики: SP і BP
Регістрові покажчики SP і BP забезпечують системі доступ до даних в сегменті стека. Рідше вони використовуються для операцій складання і віднімання.
1) регістр SP. Покажчик стека забезпечує використання стека в пам’яті, дозволяє тимчасово зберігати адреси і інколи дані. Цей регістр пов’язаний з регістром SS для адресації стека;
2) регістр BP. Покажчик бази полегшує доступ до параметрів: даним і адресам переданим через стек.
Індексні регістри: SI і DI
Обидва індексні регістри можливі для розширеної адресації і для використання в операціях складання і віднімання.
1) регістр SI. Цей регістр є індексом джерела і застосовується для деяких операцій над рядками. У даному контексті регістр SI пов’язаний з регістром DS;
2) регістр DI. Цей регістр є індексом призначення і застосовується також для строкових операцій. У даному контексті регістр DI пов’язаний з регістром ES.
Регістр командного покажчика: IP
Регістр IP містить зсув на команду, яка повинна бути виконана. Звичайно цей регістр в програмі не використовується, але він може змінювати своє значення при використанні відладчика DOS DEBUG для тестування програми.
3 ПРАКТИЧНА ЧАСТИНА
3.1 Розробка алгоритму основної програми та кожної команди, реалізованої у даній програмі
Для того, щоб користувач міг вводити потрібні йому команди для виконання ми організовуємо нескінчений цикл, який має назву «суперпетля». В цьому циклі буде виконуватись очікування, отримання та обробка потрібної команди. Цей цикл має такий вигляд:
Алгоритм основної програми:
Цикл-суперпетля — це циклічне виконання програми, в якому обирається певна подія у відповідності до певної ознаки. При чому, виконується лише одна подія за один цикл виконання суперпетлі. Суперпетля – це нескінченний цикл, але у даному випадку він повинен мати у якості однієї з подій процедуру виходу із програми (кінець виконання програми).
Головною задачею циклу-
Головною ознакою, що аналізується у даному завданні, є введена стрічка команди. В суперпетлі відбувається перевірка введеної стрічки команди з існуючими командами. У випадку, якщо порівняння виконується, то проводиться процедура виконання відповідної команди, а інакше – повідомлення про невідповідність введеної строки жодній з існуючих команд.
Рисунок 2 – Блок-схема циклу-суперпетлі
Mem
Для виконання задачі виведення на екран вільного місця оперативної пам’яті ми використовуємо команду Mem. Вона організовується при введені в стрічку самої команди Mem без параметрів.
Підпрограма Mem має такий алгоритм:
Рисунок 3 — Блок-схема команди mem
Path
Команда за теніхнічним завданням повинна виводити на екран ім’я поточного каталогу.
Рисунок 4 — Блок-схема команди path
Спочатку функція визначає номер поточного диску, i перетворює його у символьний вигляд. Далі визначається ім’я поточного каталогу і виводиться на екран разом з ім’ям диску.
Алгоритм команди path наведено в додатку Е.
Split
Формат команди за технічним завданням повинен мати наступний вигляд: після аналізу команд, дана підпрограма проводить аналіз існування вхідного файлу. У випадку, якщо даний файл існує, він відкривається для читання, і виконується подальший алгоритм його обробки. Інакше, якщо файл не існує, виводиться інформація про неіснування даного файлу, і підпрограма припиняє своє виконання.
У випадку, якщо файл знайдено і відкрито, відкриваються два вихідних файли для запису. У випадку, якщо файли не існували, вони будуть створені програмою, однак якщо вони вже були створені, то необхідно бути обережним, оскільки вони будуть цілком перезаписаними програмою, і всі попередні дані будуть втраченими.
Алгоритм команди split наведено в додатку Г.
Dir
За технічним завданням команда повинна виводити на екран список файлів у поточній директорії. Команда Dir побудована на комбінації існуючих команд.
Рисунок 5 — Блок-схема команди dir
3.2 Опис підходів та системних функцій покладених у їх основу
Опис функцій, які використовувались при написанні програми.
Функція fopen
Функція fopen ( ) відкриває потік і пов'язує з цим потоком певний файл. Потім вона повертає покажчик цього файлу. Найчастіше під файлом мається на увазі дисковий файл. Прототип функції fopen ( ) такий:
FILE *fopen (const char * filename, const char * mode);
filename — це покажчик на рядок символів, що є допустимим ім'ям файлу, в яке також може входити специфікація шляху до цього файлу. Рядок, на яку вказує mode, визначає, яким чином файл буде відкритий.
Функція fopen ( ) повертає покажчик файлу.
Параметр mode, яка використовується при виклику fopen, може приймати одне з наступних значень:
Таблиця 1 – Значення параметру mode
Режим |
Опис |
r |
Відкрити тільки для читання. |
w |
Створити для запису. Якщо файл із таким ім'ям вже існує, то він буде переписаний. |
a |
Додати; відкрити для запису в кінець чи файлу створити для запису, якщо файл не існує. |
r+ |
Відкрити існуючий файл для зміни (запис і читання). |
w+ |
Створити новий файл для зміни (запис і читання). Якщо файл із таким ім'ям вже існує, то він буде переписаний. |
a+ |
Відкрити для додавання; відкрити (чи створити, якщо файл не існує) для додавання в кінець файлу. |
Для зазначення того, що файл чи відкривається чи створюється в текстовому режимі, додайте t до рядка mode (rt, w+t, і т.д.); аналогічно, для завдання двійкового режиму слід додати b до рядка mode (wb, a+b, і т.д.). fopen також дозволяє вміщувати символи t і b між буквою і символом +. Наприклад, використання rt+ еквівалентно r+t.
Якщо t і b не зазначені в рядку mode - режим визначається значенням глобальної перемінний _fmode. Якщо _fmode встановлена в O_BINARY, то файли відкриваються в двійковому режимі. Якщо _fmode встановлена в O_TEXT - файли відкриваються в текстовому режимі. Ці константи O_ ... визначені у файлі fcntl.h.
Коли файл відкривається для зміни, над результуючим потоком можуть бути зроблені як введення, так і виведення. Однак виведення не може відразу випливати за введенням без утручання функції fseek чи rewind, як і введення не може відразу випливати за висновком без утручання функцій fseek чи rewind, чи за введенням, що зустрічає кінець файлу.
Функція fclose
Информация о работе Програма емуляції роботи командного процесора операційної системи