diff --git a/OPD/OPDLab4/guide.md b/OPD/OPDLab4/guide.md deleted file mode 100644 index cd40763..0000000 --- a/OPD/OPDLab4/guide.md +++ /dev/null @@ -1,442 +0,0 @@ -# Гайд по 4 лабораторной работе по ОПД - ---- - -## Содержание - -- [Введение](#Введение) - -- [Стек](#Стек) - - - [Основы](#Основные-понятия) - - - [Реализация в БЭВМ](#Базовая-ЭВМ) - -- [Подпрограммы](#Подпрограммы) - -- [Команды](#Команды) - - - [Адресация относительно стека](#Косвенная-относительная-адресация-со-смещением-относительно-SP) - - - [POP](#POP) - - - [POPF](#POPF) - - - [PUSH](#PUSH) - - - [PUSHF](#PUSHF) - - - [SWAP](#SWAP) - - - [CALL](#CALL) - - - [RET](#RET) - - - [IRET](#IRET) - -- [Источники](#Источники) - ---- - -## Введение - -Здесь вкратце описана инфрмация, необходимая для защиты 4 лабы по ОПД. - -## Стек - -### Основные понятия - -> **Стек** - это структура данных, рабтающая по принципу LIFO (Last-In-First-Out), или "последним зашёл, первым вышел". - -Стек можно представить как стопку книг. Книги можно ставить друг на друга только сверху, и чтобы достать какую-то определённую книгу, придётся сначала снять все остальные. - -В основном для взаимодействия со стеком используются два действия: положить на стек и снять со стека. - -### Базовая ЭВМ - -*Всё, что описано ниже, верно для актуальной версии эмулятора базовой ЭВМ (bcomp-ng v1.45.09).* - -Для взаимодействия со стеком используется ряд команд, среди которых [POP](#POP), [POPF](#POPF), [PUSH](#PUSH), [PUSHF](#PUSHF) и [SWAP](#SWAP). Все они подробно рассмотрены ниже. - -Сам стек распологается в последних ячейках памяти БЭВМ (точнее, он заполняется, начиная с последней ячейки памяти). Для управления стеком используется 11-разрядный регистр указателя стека (Stack Pointer - SP), который показывает последнюю заполненную ячейку стека. По умолчанию значение SP равно 0, что означает, что стек пуст (*также это можно рассматривать и с другой стороны: указатель стека ставится на одну ячейку ниже той, в которую будет записано следующее его значение, и тогда 0 в SP будет образовываться из-за переполнения, а точнее добавления 1 к номеру последней ячейки памяти, то есть 7FF*). - -## Подпрограммы - -*Всё, что описано ниже, верно для актуальной версии эмулятора базовой ЭВМ (bcomp-ng v1.45.09).* - -В актуальной версии БЭВМ подпрограммы являются некой мини-программой, которую удобно применять в случае, если какие-либо однотипные действия в основной программе выполняются по несколько раз. - -Для вызова подпрограммы и возврата из неё предусмотрен ряд команд, среди которых [CALL](#CALL), [RET](#RET), [IRET](#IRET). - -В БЭВМ использование подпрограмм сильно переплетено с использованием стека. В основном стек используется для временного хранения каких-либо данных, необходимых для выполнения подпрограммы. В частности, в стек записываются адрес возварщения подпрограммы (то есть место, где программа должна будет продолжить выполнение после выполнения подпрограммы), аргументы подпрограммы и результаты выполнения подпрограммы. - -Для передачи аргументов для подпрограммы существует три способа. - -- Для первого необходимо перед вызовом подпрограммы загрузить в стек необходимо количество параметров, а в подпрограмме выполнить с этими аргументами необходимые действия. При этом в подпрограмме в данном случае для взаимодействия со стеком используется специальный [режим адресации относительно стека](#Косвенная-относительная-адресация-со-смещением-относительно-SP) (впрочем, данный режим адресации можно использовать не только в подпрограмме). После этого результат выполнения подпрограммы может быть записан в те же ячейки стека, где передавались аргументы, и завершить работу подпрограммы. - -- Также можно передавать аргументы для подпрограммы и используя регистры общего назначения (к сожалению, в БЭВМ он только один, и это AC). - -- Третьим способом будет использование косвенной адресации. Для этого сразу под командой CALL можно указать заранее определённое подпрограммой количество аргументов. При этом в самой подпрограмме можно выгрузить вершину стека (которая в тот момент времени будет являться адресом первого аргумента), а после косвенной адресацией (а точнее, косвенной постинкрементацией) загрузить и использовать эти аргументы в подпрограмме. Далле остаётся только обратно загрузить уже увеличенное значение возврата подпрограммы, и программа начнет выполнение команд, которые идут уже после аргументов. - -## Команды - -### Косвенная относительная адресация со смещением относительно 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** - - - По фронту находит по адресу ячейку. - - - По спаду записывает значение этой ячейки в регистр данных. - -- 3 такт: **DR -> AC** - - - По фронту пускает значение регистра данных через АЛУ. - - - По спаду запишет его в аккумулятор. - -- 4 такт: **SP + 1 -> SP** - - - По фронту пустит значение указателя стека в АЛУ и прибавит 1. - - - По спаду запишет полученное значение в указатель стека. - -*После выполнения поставит флаги в соответствии с выгруженным значением, при этом не изменив флаг переноса и обнулив флаг переполнения*. - -Циклы выборки адреса и выборки операнда выполняться не будут, так как команда безадресная. - -### POPF - -Код: 0900. - -Выгружает верхнее значение стека в регистр состояния. - -Безадресная команда. - -#### Цикл исполнения - -- 1 такт: **SP -> AR** - - - По фронту пускает значение регистра через АЛУ. - - По спаду записывает его в адрсный регистр. - -- 2 такт: **MEM(AR) -> DR** - - - По фронту находит по адресу ячейку. - - По спаду записывает значение этой ячейки в регистр данных. - -- 3 такт: **DR -> PS** - - - По фронту пустит значение регистра данных в АЛУ. - - - По спаду запишет это значение в регистр состояния. - -- 4 такт: **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** - - - По фронту найдёт ячейку по адресу. - - - По спаду запишет значение этой ячейки в регистр данных. - -- 3 такт: **DR -> IP** - - - По фронту пустит значение регистра данных в АЛУ. - - - По спаду запишет это значение в счетчик команд. - -- 4 такт: **SP + 1 -> SP** - - - По фронту пустит значение указателя стека в АЛУ и прибавит 1. - - - По спаду запишет полученное значение в указатель стека. - -*Не меняет флаги.* - -Циклы выборки адреса и выборки операнда выполняться не будут, так как команда безадресная. - -### IRET - -Код: 0B00. - -Записывает верхнее значение стека в регистр состояния, а после прекращает выполнение подпрограммы. - -Безадресная команда. - -#### Цикл выборки операнда - -- #### Цикл исполнения - -- 1 такт: **SP -> AR** - - - По фронту пустит значение указателя стека через АЛУ. - - - По спаду запишет это значение в адресный регистр. - -- 2 такт: **MEM(AR) -> DR** - - - По фронту найдёт ячейку по адресу. - - - По спаду запишет значение этой ячейки в регистр данных. - -- 3 такт: **DR -> PS** - - - По фронту пустит значение регистра данных в АЛУ. - - - По спаду запишет это значение в регистр состояния. - -- 4 такт: **SP + 1 -> SP, AR** - - - По фронту пустит значение указателя стека в АЛУ и прибавит 1. - - - По спаду запишет полученное значение в указатель стека и в адресный регистр. - -- 5 такт: **MEM(AR) -> DR** - - - По фронту найдёт ячейку по адресу. - - - По спаду запишет значение этой ячейки в регистр данных. - -- 6 такт: **DR -> IP** - - - По фронту пустит значение регистра данных в АЛУ. - - - По спаду запишет это значение в счетчик команд. - -- 7 такт: **SP + 1 -> SP** - - - По фронту пустит значение указателя стека в АЛУ и прибавит 1. - - - По спаду запишет полученное значение в указатель стека. - -*Флаги, соответственно, возьмутся из регистра состояния.* - -Циклы выборки адреса и выборки операнда выполняться не будут, так как команда безадресная. - ---- - -## Источники - -[Методические указания к предмету](https://se.ifmo.ru/documents/10180/38002/Методические+указания+к+выполнению+лабораторных+работ+и+рубежного+контроля+БЭВМ+2019+bcomp-ng.pdf/d5a1be02-ad3f-4c43-8032-a2a04d6db12e) - -[Подсказка от моего друга и одногруппника](https://github.com/dxunvrs/ITMO/blob/master/OPD/Lab4/lab4_hint.md) - -И конечно всеми любый гугл (вообще, яндекс поисковик, но это не важно). diff --git a/OPD/OPDLab4/main.asm b/OPD/OPDLab4/main.asm deleted file mode 100644 index 3a855e0..0000000 --- a/OPD/OPDLab4/main.asm +++ /dev/null @@ -1,46 +0,0 @@ -ORG 0x05C6 -START: CLA -ST result -LD X -INC -PUSH -CALL 0x06E5 -POP -ADD result -ST result -LD Z -PUSH -CALL 0x06E5 -POP -ADD result -ST result -LD Y -DEC -PUSH -CALL 0x06E5 -POP -SUB result -ST result -HLT -Z: WORD 0xFFF4 -Y: WORD 0x0000 -X: WORD 0xFDDE -result: WORD ? - -ORG 0x06E5 -LD &1 -BEQ A -BPL B -A: CMP const1 -BLT B -BEQ B -ASL -ASL -SUB &1 -ADD const2 -JUMP C -B: LD const1 -C: ST &1 -RET -const1: WORD 0xFAB3 -const2: WORD 0x0064 \ No newline at end of file diff --git a/OPD/OPDLab4/report.pdf b/OPD/OPDLab4/report.pdf deleted file mode 100644 index f36c4d3..0000000 Binary files a/OPD/OPDLab4/report.pdf and /dev/null differ