Лабораторна робота №1

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
КН
Кафедра:
Не вказано

Інформація про роботу

Рік:
2015
Тип роботи:
Лабораторна робота
Предмет:
Системне програмування та операційні системи

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти і науки України Національний університет “Львівська політехніка” / Лабораторна робота № 1 Тема: “Особливості програмування з використанням 32-розрядного Асемблера” Львів 2015 Мета: Ознайомитись з програмною моделлю 32-розрядних мікропроцесорів Intel та оволодіти навиками створення програм, використовуючи 32-розрядний Асемблер. ТЕОРЕТИЧНІ ВІДОМОСТІ Основою для розробки низькорівневого системного програмного забезпечення є програмна модель комп’ютера, частиною якої є програмна модель мікропроцесора. До складу програмної моделі мікропроцесорів Intel сімейства x86 входять 32 регістри в тій чи іншій мірі доступні для використання програмістом. Дані регістри можна розділити на дві великі групи: 16 регістрів користувача; 16 системних регістрів. програмах на мові асемблера регістри використовуються дуже інтенсивно. Більшість регістрів мають певне функціональне призначення. Регістри користувача Як випливає з назви, призначеними для користувача регістри називаються тому, що програміст може використовувати їх при написанні своїх програм. До цих регістрів відносяться (рис.1.1): вісім 32-бітових регістрів, які можуть використовуватися програмістами для зберігання даних і адрес (їх ще називають регістрами загального призначення (РЗП)): eax/ax/ah/al; ebx/bx/bh/bl; edx/dx/dh/dl; ecx/cx/ch/cl; ebp/bp; esi/si; edi/di; esp/sp. шість сегментних регістрів: cs, ds, ss, es, fs, gs; Pегістри загального призначення eax    ax       ah   al             31 15  7 0   ebx    bx       bh   bl             31 15 7 0   ecx    cx       ch   cl             31 15 7 0   ebx    bx       bh   bl             31 15 7 0   ebp    bp              31 15   0   esi    si              31  15   0   edi    di              31  15   0   esp    sp              31  15   0    Pегістри управління та стану eflags    flags           31 15 0   eip    ip           31 15 0    Сегментні регістри cs     15 0   ss     15 0   ds     15 0   es     15 0   ts     15 0   qs     15 0   Рис. 1.1. Регістри користувача мікропроцесорів i486 і Pentium Як видно з рис. 1.1, частина регістрів зображені розділено. Це не різні регістри — це частини одного великого 32-розрядного регістру. Їх можна використовувати в програмі як окремі об’єкти. Так зроблено, для забезпечення сумісності з програмами, написаними для ранніх, 16-розрядних, моделей мікропроцесорів фірми Intel, починаючи з i8086. Мікропроцесори i486 і Pentium мають в основному 32-розрядні регістри. Їх кількість, за винятком сегментних регістрів, така ж, як і у i8086, але розмірність більше, що і відображено в їх позначеннях — вони мають приставку e (Extended). Регістри загального призначення Всі регістри цієї групи дозволяють звертатися до своїх “молодших” частин (див. рис. 1.1). Слід відзначити, що використовувати для самостійної адресації можна тільки молодші 16- і 8-бітові частини цих регістрів. Старші 16 біт цих регістрів як самостійні об’єкти програмування недоступні. До РЗП відносяться: eax/ax/ah/al (Accumulator register) — акумулятор. Використовується для зберігання проміжних даних. У деяких командах використання цього регістра обов’язкове; ebx/bx/bh/bl (Base register) — базовий регістр. Зазвичай застосовується для зберігання базової адреси деякого об’єкту в пам’яті; ecx/cx/ch/cl (Count register) — регістр-лічильник. Застосовується в командах, що проводять деякі дії, що повторюються. Його використання часто неявно і приховано в алгоритмі роботи відповідної команди. Наприклад, команда організації циклу loop окрім передачі управління команді, що знаходиться за деякою адресою, аналізує і зменшує на одиницю значення регістра ecx/cx; edx/dx/dh/dl (Data register) — регістр даних. Так само, як і регістр eax/ax/ah/al, зберігає проміжні дані. У деяких командах його використання обов’язкове, а для деяких це відбувається неявно. Наступні два регістри використовуються для підтримки операцій, що проводять послідовну обробку ланцюжків елементів, кожний з яких може мати довжину 32, 16 або 8 біт: esi/si (Source Index register) — індекс джерела. edi/di (Destination Index register) — індекс приймача (одержувача). архітектурі мікропроцесора на програмно-апаратному рівні підтримується така структура даних, як стек. Для роботи із стеком в системі команд мікропроцесора є спеціальні команди, а в програмній моделі мікропроцесора для цього існують спеціальні регістри: esp/sp (Stack Pointer register) — регістр покажчика стеку. Містить покажчик вершини стеку в поточному сегменті стеку. ebp/bp (Base Pointer register) — регістр покажчика бази кадру стеку. Призначений для організації довільного доступу до даних усередині стеку. Жорстке закріплення регістрів для деяких команд дозволяє компактніше кодувати їх машинне подання. Знання цих особливостей дозволяє при необхідності хоч би на декілька байтів заощадити пам’ять, що займається кодом програми. Робота з масивами Регістри загального призначення використовуються для адресації масивів. При цьому застосовується адресація за базою з масштабуванням: початкова адреса + база * масштабуючий коефіцієнт бази. Допустимі значення масштабуючого коефіцієнту бази (кількість байтів, які займає 1 елемент масиву) рівні 1, 2, 4, 8. Таким чином, щоб записати 3-й елемент масиву оголошеного мовою С як short arr[15] в edx треба написати код: mov eax, arr mov ebx, 2 mov edx,[eax+ebx*2] Сегментні регістри У програмній моделі мікропроцесора є шість сегментних регістрів: cs, ss, ds, es, gs та fs. Їх існування обумовлено специфікою організації і використання оперативної пам’яті мікропроцесорами Intel. Вона полягає в тому, що мікропроцесор апаратно підтримує структурну організацію програми у вигляді трьох частин, що називаються сегментами. Відповідно, така організація пам’яті називається сегментною. Для того, щоб вказати на сегменти, до яких програма має доступ в конкретний момент часу, і призначені сегментні регістри. Фактично, з невеликою поправкою, як показано далі, в цих регістрах містяться адреси пам’яті з яких починаються відповідні сегменти. Логіка обробки машинної команди побудована так, що при вибірці команди доступу до даних програми або до стеку неявно використовуються адреси з певних сегментних регістрів. Мікропроцесор підтримує наступні типи сегментів: Сегмент коду. Містить команди програми. Для доступу до цього сегменту служить регістр cs (code segment register) — сегментний регістр коду. Він містить адресу сегменту з машинними командами, до якого має доступ мікропроцесор (тобто ці команди завантажуються в конвейєр мікропроцесора). Сегмент даних. Містить оброблювані програмою дані. Для доступу до цього сегменту служить регістр ds (data segment register) — сегментний регістр даних, який зберігає адресу сегменту даних поточної програми. Сегмент стеку. Цей сегмент є ділянкою пам’яті, що називається стеком. Роботу із стеком мікропроцесор організовує за наступним принципом: останній записаний в цю ділянку елемент вибирається першим. Для доступу до цього сегменту служить регістр ss (stack segment register) — сегментний регістр стеку, що містить адресу сегменту стеку. Додатковий сегмент даних. Неявно алгоритми виконання більшості машинних команд припускають, що оброблювані ними дані розташовані в сегменті даних, адреса якого знаходиться в сегментному регістрі ds. Якщо програмі недостатньо одного сегменту даних, то вона має можливість використовувати ще три додаткові сегменти даних. Але на відміну від основного сегменту даних, адреса якого міститься в сегментному регістрі ds, при використанні додаткових сегментів даних їх адреси потрібно указувати явно за допомогою спеціальних префіксів перевизначення сегментів в команді. Адреси додаткових сегментів даних повинні міститися в регістрах es, gs, fs (extension data segment registers). Регістри стану і управління У мікропроцесор включені декілька регістрів (див. рис. 1.1), які постійно містять інформацію про стан як самого мікропроцесора, так і програми, команди якої в даний момент завантажені в конвеєр. До цих регістрів відносяться: регістр прапорів eflags/flags; регістр покажчика команди eip/ip. Використовуючи ці регістри, можна одержувати інформацію про результати виконання команд і впливати на стан самого мікропроцесора. Розглянемо докладніше призначення і вміст цих регістрів. eflags/flags (flag register) — регістр прапорів. Розрядність eflags/flags — 32/16 бітів. Окремі біти даного регістра мають певне функціональне призначення і називаються прапорцями. Молодша частина цього регістра повністю аналогічна регістру flags для i8086. На рис. 1.2 показано вміст регістра eflags. Виходячи з особливостей використання, прапори регістра eflags/flags можна розділити на три групи: 8 прапорців стану. Ці прапорці можуть змінюватися після виконання машинних команд. Прапорці стану регістра eflags відображають особливості результату виконання арифметичних або логічних операцій. Це дає можливість аналізувати стан обчислювального процесу і реагувати на нього за допомогою команд умовних переходів і викликів підпрограм. 1 прапорець управління. Позначається df (Directory Flag). Він знаходиться в 10-му біті регістру eflags і використовується для операцій рядками даних. Значення прапорця df визначає напрям поелементної обробки в цих операціях: від початку рядка до кінця або навпаки, від кінця рядка до його початку (df = 1). Для роботи з прапорцем df існують спеціальні команди: cld (зняти прапорець df) і std (встановити прапорець df). Застосування цих команд дозволяє привести прапорець df у відповідність з алгоритмом і забезпечити автоматичне збільшення або зменшення лічильників при виконанні операцій з рядками; 5 системних прапорців, для керування вводом/виводом, маскованими перериваннями, відлагодженням, перемиканням між завданнями і віртуальним режимом 8086. Прикладним програмам не рекомендується модифікувати без необхідності ці прапорці, оскільки в більшості випадків це приведе до переривання роботи програми.             Прапорці стану:                         переповнення  знаку    нуля  додаткового переносу                      рівень привілеїв вводу-виводу                                           парності                             вкладеності задач                            переносу                                                                            31 … 18 17 16 15 14 13 12 11 10 09 08 07  06 05  04 03  02 01 00                                            0 … AC VM RF 0 NT IOPL OF  DF IF TF SF ZF 0  AF 0  PF 0 CF                                                  Прапорець керування:      Системні прапорці:                     напряму       трасування                                                                                                  переривання                                                                відновлення                                                                віртуального режиму 8086                                                      контролю вирівнювання                                  Рис. 1.2. Вміст регістра eflags eip/ip (Instraction Pointer register) — регістр-покажчик команд. Регістр eip/ip має розрядність 32/16 бітів і містить зміщення до наступної команди, що має виконуватись, відносно адреси записаної в сегментний регістр cs. Цей регістр безпосередньо недоступний програмісту, але завантаження і зміна його значення проводяться різними командами управління, до яких відносяться команди умовних і безумовних переходів, виклику і повернення з процедур. Виникнення переривань також приводить до модифікації регістра eip/ip. Системні регістри мікропроцесора Сама назва цих регістрів говорить про те, що вони виконують специфічні функції в системі. Використання системних регістрів жорстко регламентовано. Саме вони забезпечують роботу захищеного режиму. Їх також можна розглядати як частина архітектури мікропроцесора, яка навмисно залишена видимою для того, щоб кваліфікований системний програміст міг виконати самі низькорівневі операції. Системні регістри можна розділити на три групи: чотири регістри управління; чотири регістри системних адрес; вісім регістрів відлагодження. Виконання лабораторної роботи: Завдання: Створити, використовуючи мову асемблера мікропроцесорів сімейства x86 Intel, *.exe програму, яка реалізовує обчислення, заданого варіантом виразу. A = {a[i]} – наперед заданий масив з N чисел цілих чисел. c, d – цілі константи. K, L – цілі додатні числа. Переконатися у правильності роботи програми використовуючи VKDebug. Скласти звіт про виконану роботу з приведенням тексту програми. Дати відповідь на контрольні запитання. Варіант №3: Знайти число додатних елементів у А Код програми: .586 .model flat, stdcall option casemap: none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\debug.inc include \masm32\include\user32.inc includelib\masm32\lib\kernel32.lib includelib\masm32\lib\masm32.lib includelib\masm32\lib\debug.lib .data Arr dd 2,5,1,-2,3,4,0,-3,-5 Count dd 0 ArrSize dd 9 .code main: mov ecx,ArrSize cout: dec ecx mov eax,[Arr+ecx*4] PrintDec eax," " cmp ecx,0 jg cout mov ecx,ArrSize Looper: cmp ecx,0 je EXIT dec ecx mov eax,[Arr+ecx*4] cmp eax,0 jg CountPP jle Looper CountPP: inc Count jmp Looper EXIT: PrintDec Count,"The quantity of positive nums " Invoke ExitProcess,NULL end main Результат виконання програми: / Словесний опис алгоритму: В ArrSize зберігається розмір масиву. Зміна Count призначена для підрахунку кількості чисел які більші за 0. В регістр ecx (лічильник), заносимо розмір масиву, в даному випадку ArrSize = 9, дії які містять після мітки cout призначенні для виводу чисел масиву. Алгоритм cout: робимо декремент регістру ecx, аби перейти на перше значення масиву, заносимо елемент масиву в регістр eax виконавши mov eax,[Arr+ecx*4] і виводимо дане значення, після виводу перевіряємо чи значення ecx>0 якщо так то преходим на мітку cout виконавши jg cout, якщо ж значення ecx менше, то продовжуємо виконання коду. Алгоритм виконання Looper: перед виконанням алгоритму який міститься за міткою Looper ми оновлюємо значення лічильника mov ecx,ArrSize. Перевіряємо значення регістру ecx, якщо воно рівне нулю то виконуємо перехід на мітку EXIT, якщо більше за нуль то робимо декремент (dec ecx) і заносимо значення масиву в регістр eax, після чого порівнюємо його з нулем, якщо значення більше за 0 то переходимо на мітку CountPP де відбувається інкремент значення Count і виконання переходу на мітку Looper, якщо ж значення елементу менше за нуль то здійснюється перехід на мітку Looper для подальшого пошуку додатнього значення масиву. Після пошуку додатних елементів масиву відбудеться перехід на мтіку EXIT, де буде виведене значення Count. Висновок: Після виконання даної лабораторної роботи я ознайомилась з програмною моделлю 32-розрядних мікропроцесорів Intel та оволоділа навиками створення програм, використовуючи 32-розрядний Асемблер.
Антиботан аватар за замовчуванням

05.02.2017 16:02-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!