Files
ITMO/OPD/OPDLab4/guide.md
T

21 KiB

Гайд по 4 лабораторной работе по ОПД


Содержание


Введение

Здесь вкратце описана инфрмация, необходимая для защиты 4 лабы по ОПД.

Стек

Основные понятия

Стек - это структура данных, рабтающая по принципу LIFO (Last-In-First-Out), или "последним зашёл, первым вышел".

Стек можно представить как стопку книг. Книги можно ставить друг на друга только сверху, и чтобы достать какую-то определённую книгу, придётся сначала снять все остальные.

В основном для взаимодействия со стеком используются два действия: положить на стек и снять со стека.

Базовая ЭВМ

Всё, что описано ниже, верно для актуальной версии эиулятора базовой ЭВМ (bcomp-ng v1.45.09).

Для взаимодействия со стеком используется ряд команд, среди которых POP, POPF, PUSH, PUSHF и SWAP. Все они подробно рассмотрены ниже.

Сам стек распологается в последних ячейках памяти БЭВМ (точнее, он заполняется, начиная с последней ячейки памяти). Для управления стеком используется 11-разрядный регистр указателя стека (Stack Pointer - SP), который показывает последнюю заполненную ячейку стека. По умолчанию значение SP равно 0, что означает, что стек пуст (также это можно рассматривать и с другой стороны: указатель стека ставится на одну ячейку ниже той, в которую будет записано следующее его значение, и тогда 0 в SP будет образовываться из-за переполнения, а точнее добавления 1 к номеру последней ячейки памяти, то есть 7FF).

Подпрограммы

Всё, что описано ниже, верно для актуальной версии эиулятора базовой ЭВМ (bcomp-ng v1.45.09).

В актуальной версии БЭВМ подпрограммы являются некой мини-программой, которую удобно применять в случае, если какие-либо однотипные действия в основной программе выполняются по несколько раз.

Для вызова подпрограммы и возврата из неё предусмотрен ряд команд, среди которых CALL, RET, IRET.

В БЭВМ использование подпрограмм сильно переплетено с использованием стека. В основном стек используется для временного хранения каких-либо данных, необходимых для выполнения подпрограммы. В частности, в стек записываются адрес возварщения подпрограммы (то есть место, где программа должна будет продолжить выполнение после выполнения подпрограммы), аргументы подпрограммы и результаты выполнения подпрограммы.

Для передачи аргументов для подпрограммы необходимо перед вызовом подпрограммы загрузить в стек необходимо количество параметров, а в подпрограмме выполнить с этими аргументами необходимые действия. При этом в подпрограмме в данном случае для взаимодействия со стеком используется специальный режим адресации относительно стека (впрочем, данный режим адресации можно использовать не только в подпрограмме). После этого результат выполнения подпрограммы может быть записан в те же ячейки стека, где передавались аргументы, и завершить работу подпрограммы. Также стоит отметить, что передавать аргументы для подпрограммы можно не только через стек, но и используя регистры общего назначения (к сожалению, в БЭВМ он только один, и это AC).

Команды

Косвенная относительная адресация со смещением относительно SP

В третем ниббле имеет код C (в двоичной системе соответственно 1100), то есть имеет вид XCXX.

В ассемблере БЭВМ обозначается как &M или (SP+M), никакой разницы между данными обозначениями нет.

Как и любая другая косвенная адресация, имеет максимально 255 полученных через смещение ячеек, из которых 128 отрицательных (и не имеют практического применения из-за особенностей стека). Таким образом, максимальное количество ячеек, к которым можно получить доступ с помощью данной адресации - это 127.

Цикл выборки адреса

  • 1 такт: SXT_CR(0..7) -> BR

    • По фронту происходит дополнение знака в АЛУ (то есть значения битов 15..8 становятся равными биту 7, где отсчет битов ведётся справа налево начиная с 0).
    • По спаду результат записывается в буферный регистр.
  • 2 такт: BR + SP -> DR

    • По фронту начение буферного регистра суммируется со значением указателя стека в АЛУ.
    • По спаду результат записывается в регистр данных.

Цикл выборки операнда

  • 1 такт: DR -> AR

    • По фронту пускает значение из регистра данных через АЛУ.
    • По спаду записывает это значение в адресный регистр.
  • 2 такт: MEM(AR) -> DR

    • По фронту находит ячейку в памяти по адресу.
    • По спаду записывает значение этой ячейки в регистр данных.

POP

Код: 0800.

Выгружает верхнее значение стека в аккумулятор.

Безадресная команда.

Цикл выборки операнда

  • 1 такт: SP -> AR

    • По фронту пускает значение регистра через АЛУ.

    • По спаду записывает его в адрсный регистр.

  • 2 такт: MEM(AR) -> DR

  • По фронту находит по адресу ячейку.

  • По спаду записывает значение этой ячейки в регистр данных.

Цикл исполнения

  • 1 такт: DR -> AC

    • По фронту пускает значение регистра данных через АЛУ.

    • По спаду запишет его в аккумулятор.

  • 2 такт: SP + 1 -> SP

    • По фронту пустит значение указателя стека в АЛУ и прибавит 1.

    • По спаду запишет полученное значение в указатель стека.

После выполнения поставит флаги в соответствии с выгруженным значением, при этом не изменив флаг переноса и обнулив флаг переполнения.

Цикл выборки адреса выполняться не будет, так как команда безадресная.

POPF

Код: 0900.

Выгружает верхнее значение стека в регистр состояния.

Безадресная команда.

Цикл выборки операнда

  • 1 такт: SP -> AR

    • По фронту пускает значение регистра через АЛУ.
    • По спаду записывает его в адрсный регистр.
  • 2 такт: MEM(AR) -> DR

    • По фронту находит по адресу ячейку.
    • По спаду записывает значение этой ячейки в регистр данных.

Цикл исполнения

  • 1 такт: DR -> PS

    • По фронту пустит значение регистра данных в АЛУ.

    • По спаду запишет это значение в регистр состояния.

  • 2 такт: MEM(AR) -> DR

    • По фронту находит по адресу ячейку.
    • По спаду записывает значение этой ячейки в регистр данных.

Флаги, соответственно, возьмутся из регистра состояния.

Цикл выборки адреса выполняться не будет, так как команда безадресная.

PUSH

Код: 0C00.

Загружает значение аккумулятора на вершину стека.

Безадресная команда.

Цикл исполнения

  • 1 такт: AC -> DR
    • По фронту пустит значение аккумулятора через АЛУ.

    • По спаду запишет его в регистр данных.

  • 2 такт: ~0 + SP -> SP, AR
    • По фронту прибавит в АЛУ к значению указателя стека ~0 (то есть -1).

    • По спаду запишет это значение в указатель стека и адресный регистр.

  • 3 такт: DR -> MEM(AR)
    • По фронту найдёт ячейку по адресу.

    • По спаду запишет значение регистра данных в эту ячейку.

Не меняет флаги.

Цикл выборки адреса выполняться не будет, так как команда безадресная.

Цикл выборки операнда выполняться не будет, так как нужное нам значение уже записано в аккумуляторе.

PUSHF

Код: 0D00.

Загружает значение регистра состояния на вершину стека.

Безадресная команда.

Цикл исполнения

  • 1 такт: PS -> DR

    • По фронту пустит значение регистра состояния через АЛУ.

    • По спаду запишет это значение в регистр данных.

  • 2 такт: ~0 + SP -> SP, AR

  • По фронту прибавит в АЛУ к значению указателя стека ~0 (то есть -1).

  • По спаду запишет это значение в указатель стека и адресный регистр.

  • 3 такт: DR -> MEM(AR)

    • По фронту найдёт ячейку по адресу.
    • По спаду запишет в эту ячейку значение регистра данных.

Не меняет флаги.

Цикл выборки адреса выполняться не будет, так как команда безадресная.

Цикл выборки операнда выполняться не будет, так как нужное нам значение уже записано в регистре состояния.

SWAP

Код: 0E00.

Меняет местами значение аккумулятора и верхнее значение стека.

Безадресная команда.

Цикл исполнения

  • 1 такт: SP -> AR

    • По фронту пустит значение указателя стека через АЛУ.

    • По спаду запишет это значение в адресный регистр.

  • 2 такт: MEM(AR) -> DR

    • По фронту найдёт ячейку по адресу.

    • По спаду запишет значение этой ячейки в регистр данных.

  • 3 такт: DR -> BR

    • По фронту пустит значение регистра данных через АЛУ.

    • По спаду запишет это значение в буферный регистр.

  • 4 такт: AC -> DR

    • По фронту пустит значение аккумулятора через АЛУ.

    • По спаду запишет это значение в регистр данных.

  • 5 такт: BR -> AC; DR -> MEM(AR)

    • По фронту пустит значение буферного регистра через АЛУ, а также найдет ячейку по адресу.

    • По спаду запишет значение из АЛУ в аккумулятор, а также запишет значение регистра данных в ячейку памяти.

Ставит флаги по загруженному значению, не меняя флаг переноса и обнуляя флаг переполнения.

Цикл выборки адреса выполняться не будет, так как команда безадресная.

Цикл выборки операнда выполняться не будет, так как нужное нам значение уже записано в аккумуляторе.

CALL

Код: DXXX.

Вызывает подпрограмму по заданному адресу.

Адресная команда.

Цикл выборки адреса и цикл выборки операнда зависят от типа адресации.

Цикл исполнения

  • 1 такт: DR -> BR

    • По фронту пустит значение регистра данных через АЛУ.

    • По спаду запишет это значение в буферный регистр.

  • 2 такт: IP -> DR

    • По фронту пустит значение счетчика команд через АЛУ.

    • По спаду запишет это значение в регистр данных.

  • 3 такт: BR -> IP

    • По фронту пустит значение буферного регистра через АЛУ.

    • По спаду запишет это значение в счетчик команд.

  • 4 такт: ~0 + SP -> SP, AR

    • По фронту прибавит в АЛУ к значению указателя стека ~0 (то есть -1).

    • По спаду запишет это значение в указатель стека и адресный регистр.

  • 5 такт: DR -> MEM(AR)

    • По фронту найдёт ячейку по адресу.

    • По спаду запишет в эту ячейку значение регистра данных.

Не меняет флаги.

RET

Код: 0A00.

Прекращает выполнение подпрограммы.

Безадресная команда.

Цикл выборки операнда

  • 1 такт: SP -> AR

    • По фронту пустит значение указателя стека через АЛУ.

    • По спаду запишет это значение в адресный регистр.

  • 2 такт: MEM(AR) -> DR

    • По фронту найдёт ячейку по адресу.

    • По спаду запишет значение этой ячейки в регистр данных.

Цикл исполнения

  • 1 такт: DR -> IP

    • По фронту пустит значение регистра данных в АЛУ.

    • По спаду запишет это значение в счетчик команд.

  • 2 такт: SP + 1 -> SP

    • По фронту пустит значение указателя стека в АЛУ и прибавит 1.

    • По спаду запишет полученное значение в указатель стека.

Не меняет флаги.

Цикл выборки адреса выполняться не будет, так как команда безадресная.

IRET

Код: 0B00.

Записывает верхнее значение стека в регистр состояния, а после прекращает выполнение подпрограммы.

Безадресная команда.

Цикл выборки операнда

  • 1 такт: SP -> AR

    • По фронту пустит значение указателя стека через АЛУ.

    • По спаду запишет это значение в адресный регистр.

  • 2 такт: MEM(AR) -> DR

    • По фронту найдёт ячейку по адресу.

    • По спаду запишет значение этой ячейки в регистр данных.

Цикл исполнения

  • 1 такт: DR -> PS

    • По фронту пустит значение регистра данных в АЛУ.

    • По спаду запишет это значение в регистр состояния.

  • 2 такт: SP + 1 -> SP, AR

    • По фронту пустит значение указателя стека в АЛУ и прибавит 1.

    • По спаду запишет полученное значение в указатель стека и в адресный регистр.

  • 3 такт: MEM(AR) -> DR

    • По фронту найдёт ячейку по адресу.

    • По спаду запишет значение этой ячейки в регистр данных.

  • 4 такт: DR -> IP

    • По фронту пустит значение регистра данных в АЛУ.

    • По спаду запишет это значение в счетчик команд.

  • 5 такт: SP + 1 -> SP

    • По фронту пустит значение указателя стека в АЛУ и прибавит 1.

    • По спаду запишет полученное значение в указатель стека.

Флаги, соответственно, возьмутся из регистра состояния.

Цикл выборки адреса выполняться не будет, так как команда безадресная.


Источники

Методические указания к предмету

Подсказка от моего друга и одногруппника

И конечно всеми любый гугл (вообще, яндекс поисковик, но это не важно).