![](/user_photo/2706_HbeT2.jpg)
3. При захисті роботи пояснити, чому треба інвертувати прапорець переносу у пункті 15. Лабораторна робота №5
Тема: Операції над стеком.
Мета: Необхідно написати програму яка методом перебору знаходить оптимальний хід для гри “Сірники”.
У будь-якому мікропроцесорі для роботи зі стеком існує спеціальний регістр - вказівник стека (SP), який містить адресу верхівки стека. Стек - це така організація пам'яті, де для читання або запису даних не треба явно вказувати їх адресу. Прочитати дані після декількох операцій запису можна тільки у зворотному порядку: останнім прийшов - першим вийшов. У дійсності, адреса, за якою процесор читає та записує дані при роботі із стеком, знаходяться у регістрі "SP". Якщо при виконанні зустрічається команда "РUSH" опустити в стек, то процесор зменшує (SP) на два, та розміщує дані у пам'яті за його адресою, по команді "POP" процесор виконує зворотні дії: читає дані за адресою (SP) у регістрі і збільшує вміст (SP) на два. За одну операцію "PUSH" або "POP" пересилаються два спарених 8-бітних регістри. За допомогою стека реалізовано апарат виклику та повернення з підпрограм: адреса команди, на яку слід повернутись, засилаються у стек, а при поверненні витягаються та передаються у програмний лічильник (PC).
Завдання
У лабораторній роботі треба виконати програму, яка знаходить методом перебору найкращий хід в забавку "сірники", дотримуючись при виборі мінімаксної стратегії (розглядається в теорії ігор).
Умова гри: машина і людина беруть по черзі сірники із загальної купи, за один раз можна брати від одного до трьох сірників, програє той, хто бере останній сірник.
-
Вхідні дані до підпрограми: в акумуляторі - кількість сірників на N-му ході (задавати не більше #0F)
-
Вихідні дані підпрограми: у регістрі "D" - оптимальна кількість взятих машиною сірників; в акумуляторі - значення функції виграшу.
-
Константи підпрограми: у регістр "В" завантажується максимальна кількість сірників, яку можна взяти (задавати 3, 4, 5, 6).
Підпрограма для знаходження оптимального ходу
Кожний пункт співпадає з однією командою на асемблері.
-
Підготувати регістри до процесу знаходження ходу: опустити у стек вміст регістрової пари «HL»
-
Опустити у стек вміст регістрової пари «ВС».
-
Звільнити акумулятор, переслати у «С» з «А» кількість сірників, яка є на столі.
-
Підготувати початкові значення. Завантажити у «В» максимально можливу кількість сірників, яку будемо пробувати брати (див.умову).
-
Завантажити у «Н» початкове значення функції виграшу, що дорівнює нулю.
-
Головний процес (спроба ходу): переслати в акумулятор кількість сірників, яка є на столі (див. п.З).
-
Відняти від вмісту акумулятора кількість сірників, яку спробуємо взяти.
-
Перехід до п. 19, якщо результат від’ємний (встановився carry).
-
Якщо результат віднімання дорівнює нулю, то взяли останній сірник, тобто програли – перехід до п.26.
-
Порівняти результат з одиницею.
-
Якщо при порівнянні отримали нуль, то виграли – перехід до п.28.
-
Знайти оптимальний хід та значення функції виграшу для противника (рекурсивний виклик цієї підпрограми).
-
Інвертувати отриману функцію виграшу противника.
-
Збільшити результат на одиницю з метою переводу у від’ємне число.
-
Перевірити, чи зроблений хід кращий за попередні: порівняти результат з максимальним значенням функції виграшу у «Н «.
-
Перехід до п. 19, якщо цей хід не кращий (Н>А).
-
Подія: знайшли нове максимальне значення функції виграшу, яке треба зберегти в «Н».
-
Запам’ятати в «L» кількість сірників, що спробували брати, і яка привела до кращого ходу
-
Продовження перебору ходів: зменшуємо кількість сірників, яку будемо пробувати брати (вміст «В»).
-
Якщо результат зменшення не нуль, то повторити процес з п.6;
-
Інакше підготуватись до виходу з підпрограми: витягнути зі стека регістрову пару «ВС».
-
Переслати знайдене максимальне значення функції виграшу в акумулятор.
-
Переслати . в «D» кількість сірників, яка відповідає знайденому максимальному значенню функції виграшу.
-
Витягнути зі стека регістрову пару «HL».
-
Повернутись з підпрограми.
-
Програв: встановити в акумуляторі значения функції виграшу, яке дорівнює #81.
-
Продовжувати пошук. Перейти до п. 15.
-
Виграв: підготуватись до закінчення пошуку ходу – завантажити в»Н» максимальне значення функції виграшу, яке дорівнює #83.
-
Переслати в «L» кількість взятих сірників, що привели до виграшу.
-
Перейти до закінчення пошуку – п.21.
Головна програма
-
Завантажити в акумулятор кількість сірників, що залишились на столі після: N-ro ходу.
-
Знайти оптимальний хід (викликати підпрограму).
-
Підготуватись до виводу ходу – завантажити у акумулятор код програмування інтерфейсу.
-
Запрограмувати інтерфейс для виводу на світлодіоди.
-
З регістра «D» переслати у акумулятор кількість взятих програмою сірників (оптимальний хід).
-
Вивести отримане значення на світлодіоди.
-
Зупинити процесор.
При захисті роботи перевірити, чи дотримується програма оптимальної стратегії, пояснити в чому полягає принцип мінімакса.