Лабораторная работа №2 Стек
Цель работы: изучить назначение стека микропроцес-
сора 8086.
Теоретические сведения
Стек является удобной структурой данных для решения различных вычислительных задач, особенность которой в том, что она безадресная. Под термином «безадресная» подразумевается, что в команде не указывается — ни прямо, ни косвенно
— адрес ячейки стека. В большинстве современных процессоров реализован аппаратный стек, который представляет из себя специально организованное оперативное запоминающее устройство. В МП 8086 под стек отводится область в ОЗУ и используется в основном для следующих целей:
-для хранения временных данных. Программист может разместить любые данные, не задумываясь, в какую ячейку памяти они будут размещены;
-для хранения адреса возврата из подпрограммы. Вызов подпрограммы из основной программы приводит к прыжку на другой адрес памяти. Чтобы осуществить возврат из подпрограммы в основную программу микропроцессор сохраняет в стек содержимое регистров CS и IP, которые определяют адрес текущей исполняемой команды. Подпрограмма должна заканчиваться специальной командой, которая восстанавливает из стека начальные значения регистров CS и IP. Подобная схема работает и при обработке прерываний;
-для доступа к регистру флагов;
-для изменения содержимого сегментных регистров;
-для передачи параметров между программами.
Стек относится к памяти типа LIFO (Last Input First Output, последним пришел - первым вышел), что означает, что последние загруженные данные будут выгружены в первую
9
очередь. Здесь существует аналогия со стопкой тарелок: последнюю размещенную тарелку в стопке берем в первую очередь[4].
В МП 8086 каждый элемент стека занимает 2 байта, причем старший байт расположен в ОЗУ по старшему адресу, младший - по младшему. Микропроцессор для обращения к данным в стеке использует два регистра: SS и SP. Сегментный регистр SS определяет начало блока памяти, отведенного под стек, а SP - смещение последний записи от начала сегмента. Стек растет «вниз», т.е. при записи в стек данных значение регистрасчетчика SP автоматически уменьшается на 2, а при чтении данных - увеличивается на 2. Для работы со стеком используются две основные команды: PUSH и POP.
Команда PUSH. Помещает данные в стек. Формат команды: PUSH источник. Источником может быть регистр, сегментный регистр, непосредственный операнд или память. Фактически эта команда уменьшает SP на 2 и копирует содержимое источника в память по адресу SSSP.
Команда POP. Считывает данные из стека. Формат команды: POP приемник. Помещает в приемник слово, находящееся в вершине стека, увеличивая SP на 2. Приемником может быть регистр общего назначения, сегментный регистр, кроме CS, переменная.
На рис. 2 представлена схема стека при выполнении команды PUSH 6512h. Первоначально стек не содержит информации и вершина стека и его дно указывают на один и тот же адрес SS:0500h. После выполнения команды PUSH значение регистра SP уменьшается на 2 и указывает на свободный участок памяти.
10
а) |
б) |
в) |
Рис. 2. Схема стека при выполнении команды PUSH и POP а) - до выполнения команд; б) - после выполнения команды PUSH;
в) -после выполнения команды POP
После выполнения команды POP данные из стека считываются и помещаются в приемник. При этом данные в ОЗУ не исчезают, просто вершина стека указывает на другие ячейки памяти.
Команды PUSF и POPF позволяют программисту получить доступ к регистру флагов, проанализировать его и при необходимости изменить. PUSHF помещает содержимое регистра флагов в стек, а POPF возвращает слово из стека в регистр флагов [3].
Одной из причин необходимости получения доступа к регистру флагов программой является её защита от выполнения под отладчиком. Отладчик - это программа, позволяющая исследовать внутреннее устройство программы. Отладчик обеспечивает пошаговое исполнение программы, просмотр текущих значений переменных, вычисление значения любого выражения программы и другие функции.
Отладчики могут быть использованы специалистами, занимающимися безопасностью вычислительных систем, в частности, для анализа функциональности вирусов. С другой стороны, данными программами пользуются хакеры для модификации программ с целью взлома защиты от нелицензионного использования программ.
11
Одним из способов реализации пошагового выполнения программы является установка флага TF регистра флагов. В этом случае процессор после выполнения любой команды генерирует прерывание int 1h.
Программа-отладчик вначале устанавливает флаг TF и запускает исследуемую программу. После выполнения каждой команды исследуемой программы отладчик перехватывает прерывание 1h и может фиксировать текущие параметры вычислительной машины (состояние основных регистров процессора, участков памяти).
Для борьбы с данным механизмом отладки, программа должна при выполнении критически участков, например, проверки лицензионного ключа, выяснить, не установлен ли флаг TF. Если установлен, то прекращается выполнение программы. При этом необходимо учесть, что отладчик может определить попытку проанализировать регистр флагов и снять его перед проверкой, а потом снова включить. Но в процессорах семейства 8086 до 386-го после операций перемещения с сегментными регистрами не вызывается исключительная ситуация даже при установленном флаге TF. Для проверки значения флага TF можно использовать следующий код:
Задачи:
1.Изучить назначение стека микропроцессора 8086;
2.Используя эмулятор Emu8086 изучить команды
PUSH и POP;
12
3.Изменить программный код из лабораторной работы №1 пункта 4 постановки задачи таким образом, чтобы при выполнении условия выполнялось вычитание регистров R1 и R2, а иначе - их сложение за счет изменения флажка в регистре состояния с использованием стека;
4.Разработайте программный код, позволяющий поменять содержимое регистров R3 и R4, используя команды только для работы со стеком;
5.Составить отчет по работе;
6.Ответить на контрольные вопросы для самопро-
верки.
Порядок выполнения работы :
1.Изучить теоретическую часть данной работы и получить представление о назначении стека микропроцессора
8086;
2.Изучить команды PUSH и POP. Запустите эмулятор Emu8086 и создайте новый проект, выбрав в меню пункт «New». Выберите шаблон «Bin Template» и после слов «;add your code here», введите следующий код:
MOV AX,D/1 MOV BX,D/2 PUSH AX PUSH DS PUSH word[BX] POP ES
POP DX POP CX
где DI1 и DI2 значения из табл. 3.
13