
- •Основы алгоритмизации и программирования
- •29 Декабря 2011, протокол № 4
- •Введение
- •Этапы развития эвм
- •Поколения эвм
- •Машинно-ориентированные языки программирования
- •Архитектура эвм
- •Микропроцессоры intel
- •Набор регистров
- •Регистры общего назначения
- •Сегментные регистры
- •Регистры состояния и управления
- •Организация памяти
- •Сегментная организация памяти
- •Типы данных
- •Символы
- •Целые числа
- •Указатель на память
- •Цепочки
- •Вещественые числа
- •Двоично-десятичные числа (bcd)
- •Формат команд
- •Обработка прерываний
- •Int тип_прерывания
- •Синтаксис ассемблера
- •Алфавит ассемблера
- •Директивы сегментации
- •Упрощённые директивы сегментации
- •Директивы резервирования и инициализации данных
- •Операнды
- •Способы задания операндов Прямая адресация
- •Косвенная адресация
- •Косвенная базовая адресация
- •Косвенная базовая адресация со смещением
- •Косвенная индексная адресация со смещением
- •Косвенная базовая индексная адресация
- •Косвенная базовая индексная адресация со смещением
- •Операторы
- •Функциональная классификация машинных команд
- •Команды пересылки данных Команды общего назначения
- •Работа с адресами и указателями
- •Преобразование данных
- •Xlat [адрес_таблицы_перекодировки]
- •Ввод из порта и вывод в порт
- •Работа со стеком
- •Арифметические команды Форматы арифметических данных
- •Арифметические операции над целыми двоичными числами
- •Логические команды
- •Команды передачи управления
- •Команда безусловного перехода
- •Условные переходы
- •Организация циклов
- •Основы алгоритмизации и программирования
Преобразование данных
Команда преобразования данных XLAT имеет следующий формат записи:
Xlat [адрес_таблицы_перекодировки]
Действие этой команды заключается в том, что она замещает значение в регистре AL другим байтом из таблицы в памяти, расположенной по адресу, указанному операндом адрес_таблицы_перекодировки. Под «таблицей» подразумевается строка байтов. Адрес байта в строке, которым будет производиться замещение содержимого регистра AL, определяется суммой (ВХ) + (AL), то есть содержимое AL играет роль индекса в байтовом массиве.
Хотя в команде указывается адрес строки байтов, из которой должно быть извлечено новое значение, этот адрес должен быть предварительно загружен (например, с помощью команды LEA) в регистр ВХ. Таким образом, операнд адрес_таблицы_перекодировки на самом деле не нужен (на это указывают квадратные скобки).
Что касается строки байтов (таблицы перекодировки), то она представляет собой область памяти размером от 1 до 255 байт (диапазон числа без знака в 8-разрядном регистре).
Ввод из порта и вывод в порт
Порт ввода-вывода может быть операндам машинной команды. Физически порт ввода-вывода представляет собой регистр разрядностью 8, 16 или 32 бита. Доступ к устройствам ввода-вывода, системным устройствам компьютера осуществляется посредством их регистров, причем каждый из этих регистров должен иметь возможность уникальной идентификации. С этой целью архитектурно процессор поддерживает так называемое адресное пространство ввода-вывода.
Комаанды для работы с портами ввода-вывода:
in <аккумулятор>,<номер_порта> — ввод в аккумулятор из порта с номером <номер_порта>;
out <номер_порта>,<аккумулятор> — вывод содержимого аккумулятора в порт с номером <номер_порта>.
Работа со стеком
Стек – это область памяти, специально выделяемая для временного хранения данных программы. Важность стека определяется тем, что для него в структуре программы предусмотрен отдельный сегмент. На тот случай, если программист забыл описать сегмент стека в своей программе, компоновщик TLINK выдаст предупреждающее сообщение.
Для работы со стеком предназначены три регистра:
SS — регистр сегмента стека;
SP— регистр указателя стека;
ВР— регистр указателя базы кадра стека.
Размер стека зависит от режима работы процессора и ограничивается значением 64 Кбайт (или 4 Гбайт в защищенном режиме). В каждый момент времени доступен только один стек, адрес сегмента которого содержится в регистре SS. Этот стек называется текущим. Для того чтобы обратиться к другому стеку («переключить стек»), необходимо загрузить в регистр SS другой адрес. Регистр SS автоматически используется процессором для выполнения всех команд, работающих со стеком.
Перечислим еще некоторые особенности работы со стеком.
Запись и чтение данных в стеке осуществляются в соответствии с принципом LIFO (Last In First Out — «последним пришел, первым ушел»).
По мере записи данных в стек последний растет в сторону младших адресов. Эта особенность заложена в алгоритм команд работы со стеком.
При использовании регистров SP и ВР для адресации памяти ассемблер автоматически считает, что содержащиеся в нем значения представляют собой смещения относительно сегментного регистра SS.
Рисунок 11. Схема организации стека
Регистры SS, SP и ВР используются комплексно, и каждый из них имеет свое функциональное назначение. Регистр SP всегда указывает на вершину стека, то есть содержит смещение, по которому в стек был занесен последний элемент. Команды работы со стеком неявно изменяют этот регистр так, чтобы он указывал всегда на последний записанный в стек элемент. Если стек пуст, то значение SP равно адресу последнего байта сегмента, выделенного под стек. При занесении элемента в стек процессор уменьшает значение регистра SP, а затем записывает элемент по адресу новой вершины. При извлечении данных из стека процессор копирует элемент, расположенный по адресу вершины, а затем увеличивает значение регистра указателя стека SP. Таким образом, получается, что стек растет вниз, в сторону уменьшения адресов.
Что нужно сделать для получения доступа к элементам не на вершине, а внутри стека? Для этого применяют регистр ВР. Регистр ВР — регистр указателя базы кадра стека. Например, типичным приемом при входе в подпрограмму является передача нужных параметров путем записи их в стек. Если подпрограмма тоже активно работает со стеком, то доступ к этим параметрам становится проблематичным. Выход в том, чтобы после записи нужных данных в стек сохранить адрес вершины стека в указателе базы кадра стека — регистре ВР. Значение в ВР в дальнейшем можно использовать для доступа к переданным параметрам.
Начало стека расположено в старших адресах памяти. На рис. 11 этот адрес обозначен парой SS:ffff. Смещение ffff приведено здесь условно. Реально это значение определяется величиной, которую программист задает при описании сегмента стека в своей программе. К примеру, если в программе написана директива stack 100h, началу стека будет соответствовать пара SS:0100h. Адресная пара SS:ffff — это максимальное для реального режима значение адреса начала стека, так как размер сегмента в нем ограничен величиной 64 Кбайт (0ffffh).
Для организации работы со стеком существуют специальные команды записи и чтения.
Команда PUSH выполняет запись значения <источник> в вершину стека:
push <источник>
Алгоритм работы этой команды, который включает два действия (рис. 12):
1. Значение SP уменьшается на 2: (SP) = (SP) - 2
2. Значение источника записывается по адресу, указываемому парой SS:SP.
Рисунок 12. Принцип работы команды PUSH
Команда POP выполняет запись значения из вершины стека по месту, указанному операндом <приемник> (значение при этом «снимается» с вершины стека):
pop <приемник>
Алгоритм работы команды POP обратен алгоритму команды PUSH (рис. 13).
1. Запись содержимого вершины стека по месту, указанному операндом <приемник>.
2. Увеличение значения SP: (SP) = (SP) + 2
Рисунок 13. Принцип работы команды POP
Команда PUSHA предназначена для групповой записи в стек. По этой команде в стек последовательно записывается содержимое регистров АХ, СХ, DX, BX, SP, BP, SI, DI. Заметим, что записывается оригинальное содержимое SP, то есть то, которое было до выдачи команды PUSHA (рис. 14).
Рисунок 14. Принцип работы команды PUSHA
Команда РОРА выполняет действие, обратное действию команды PUSHA.
Команда PUSHF сохраняет регистр флагов в стеке. Команда POPF выполняет действие, обратное действию команды PUSHF.