Пятница, 15.12.2017, 09:21
БК-0010.01. Повесть о настоящем компьютере
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
Меню сайта
Категории каталога
Введение в руководство [2]
Введение [0]
Организация БК-0010 [1]
Раздел 1. Организация БК-0010
Работа с МСД [1]
Раздел 2. Работа с МСД
Системные регистры [1]
Раздел 3. Системные регистры
Системное ПО [1]
Раздел 4. Системное программное обеспечение БК-0010
Прерывания. Приоритет ЦП [1]
Раздел 5. Система прерываний БК-0010. Приоритет процессора
Командные прерывания [1]
Раздел 6. Командные прерывания
ЕМТ БК-0010 [1]
Раздел 7. командные прерывания ЕМТ БК-0010
Коды и ассемблер. Мнемокод. [1]
Раздел 8. Коды и ассемблер. Мнемокод. Формат команды
Способы адресации [1]
Раздел 9. Способы адресации
Команды процессора БК-0010 [1]
Раздел 10. Система команд процессора БК-0010
Псевдокоманды. Метки. Комментарии [1]
Раздел 11. Псевдокоманды ассемблера. Метки. Комментарии
Программирование на ассемблере [1]
Раздел 12. Программирование на ассемблере. Начало. Трансляция программ. Ошибки
Отладка программ [1]
Раздел 13. Отладка программ. Позиционно-независимое программирование. Компановка
Подпрограммы ПЗУ БК-0010 [1]
Раздел 14. Подпрограммы ПЗУ БК-0010
Системная область ОЗУ БК-0010 [1]
Раздел 15. Системная область ОЗУ БК-0010. Некоторые секретные сведения об авторе и МП-клубе
Повышение быстродействия БК-0010 [1]
Раздел 16. Вопросы повышения быстродействия БК-0010
Об использовании ПЗУ [1]
Раздел 17. Полезная подпрограмма. Об использовании ПЗУ
Загадочные регистры [1]
Раздел 18. Загадочные регистры
Штурм системной области [1]
Раздел 19. Продолжаем штурм системной области
Об автозапуске программ [1]
Раздел 20. Об автозапуске программ
Коварные программы [1]
Раздел 21. Коварные программы
Еще о системной области [1]
Раздел 22. О пользе плагиата, или еще о системной области
О псевдокомандах и компановке [1]
Раздел 23. Еще раз о псевдокомандах, метках и компановке
Тук-тук, кто в стеке живет? [1]
Раздел 24. Тук-тук, кто в стеке живет?
Фокал с позиций ассемблера [1]
Раздел 25. Взгляд на фокал с позиций ассемблера
Наш опрос
Оцените мой сайт
Всего ответов: 47
 Каталог статей
Главная » Статьи » Тук-тук, кто в стеке живет?

Тук-тук, кто в стеке живет?

Помните известную русскую сказку "теремок"? Как туда один за другим залезло много зверей, и как они по очереди отвечали на вопрос "кто в тереме живет"? - &Quot;я, муха-цокотуха", "я, комар-пискун", "я, лягушка-квакушка"... Есть такой "теремок" и в БК-0010. Это стек. Что такое стек, и чем он отличается от остального ОЗУ?

Коротко мы уже не раз упоминали о стеке. Но полной ясности в этом вопросе пока нет, не правда ли? Прежде всего, стек размещен в системной области. С какого по какой адрес? С адреса 776. А вот по какой, это сложнее. Известно, что началом стека считается не его младший адрес, а старший, т.е. адрес 776. С него и начинает заполняться стек. Таким образом, говоря, что "стек растет", мы имеем в виду, что текущий адрес стека становится... Все меньше!

Этот текущий адрес называют вершиной стека. Именно адрес вершины стека постоянно хранится в R6, или SP. До каких пределов может расти стек?
очевидно, пока есть место! Вспомним, до какого адреса ячейки системной области БК имеют определенное назначение?

Последние ячейки системной области с фиксированной функцией - это блок параметров драйвера магнитофона, адреса 320...371.
Вот до адреса 372 и может в принципе расти стек без каких-либо ограничений. Это- так называемая "зеленая зона". Если мы не пользуемся драйвером магнитофона, или выделим для него буфер под блок параметров в другом месте, то можно "залезть" в "желтую зону"- использовать под стек и адреса по 320-й.
А вот дальше уже "красная зона", и дальнейший рост стека приводит к необратимой порче системной области. Т.к. раньше всего идут там ячейки, содержащие маски фона и символа, то порча стеком системной области прежде всего проявляется в том, что на экране появляются вертикальные полосы. Затем очень быстро оказываются запорченными и более "серьезные" ячейки, и ЭВМ прекращает работу.

В отличие от СМ-4, БК-0010 не имеет специального ограничителя стека, который вызывал бы прерывание при нарушении стеком границы "красной зоны".
Далее, стек - это специально выделенная область памяти, которой ЭВМ может распоряжаться "сама", если даже пользователь не вводил в программу специальных команд для операций со стеком. Например, при прерывании программы (любом, а не только командном ЕМТ или TRAP), в стек прежде всего заносится адрес возврата, т.е. Содержимое PC в момент прерывания. А там - адрес следующей команды. Затем вершина стека смещается на 2 (SP становится на 2 меньше), и в стек заносится слово состояния дисплея (ССД).

Когда же обработка прерывания закончится, команда RTI извлечет из стека ССД и запишет его в спец.Регистр (PS) процессора (восстановит ССД), а затем перепишет адрес возврата в PC, и таким образом, следующей станет исполняться команда, адрес которой был в PC до прерывания. Совершенно аналогично записывается в стек адрес возврата и при обращении к п/программе, с той разницей, что ССД в стек не заносится.

А может ли использоваться стек программой пользователя? Да, и очень широко. Чаще всего используют стек для временного хранения содержимого регистров общего назначения. Как это делается? Положим, нам нужно освободить для каких-либо целей регистры R1, R2, R3, но при этом сохранить их содержимое. Запишем:

MOV R1,-(SP)
MOV R2,-(SP)
MOV R3,-(SP)

Три регистра помещены в стек, причем первым - R1, он дальше всего от вершины, последним - R3, он - на вершине стека.
Адрес вершины стека при этом изменился, и стал меньше на 6 (вспомним, что адресация с автодекрементом изменяет аргумент на 2, и делает это до пересылки). Каковы же теперь физические адреса содержимого R1...R3,и как им при необходимости воспользоваться? Для ответа на этот вопрос нужно знать, каково было содержимое SP до операции. В МСД исходное содержимое SP=732. Если до пересылки регистров в стек он не использовался, то адреса содержимого регистров будут:
R1=730; R2=726; R3=724.
SP=724.

Но для того, чтобы "добраться" до содержимого регистров, совсем не обязательно точно знать их адреса, достаточно знать порядок их засылки в стек. Допустим, чтобы переписать содержимое вершины стека в R0, нужно сделать:

MOV (SP),R0. Это - содержимое R3.

для R2:
MOV 2(SP),R0;

для R1:
MOV 4(SP),R0.

т.е. мы задаем не абсолютный адрес, а расстояние нужной информации от вершины. А если нужно будет восстановить содержимое всех 3 регистров? Тогда нужно выполнить:

MOV (SP)+,R3
MOV (SP)+,R2
MOV (SP)+,R1

Поскольку порядок записи в регистры обратный записи в стек, а автоинкремент делается после пересылки, то содержимое регистров будет восстановлено правильно, а адрес вершины стека будет равен исходному. Можно использовать стек и для обмена содержимым регистров, например:

MOV R0,-(SP)
MOV R1,R0
MOV (SP)+,R1

В этом примере содержимое регистров R0 и R1 меняется местами.

Вообще, со стеком можно делать любые операции, которые можно задать методом косвенной адресации. Многие из таких операций требуют для записи всего 1 слова, и выполняются гораздо быстрее операций с выделенной ячейкой памяти (буфером). Сравните:

MOV R0,-(SP) и MOV R0,buf

Первая операция выполняется почти вдвое быстрее, не требует выделения ячейки памяти (buf), и занимает всего 1 слово (2-два).
Если уж преимущества работы со стеком так велики, вправе вы спросить, то почему же не выполнять с ним все операции, зачем все-таки иногда выделять ячейки памяти (переменные) для хранения данных? Дело в том, что для того, чтобы иметь дело со стеком, нужно очень четко представлять, где и какая информация со- держится в нем в данный момент. А это не всегда легко. В процессе исполнения программы возможны прерывания, обращения к подпрограммам, а это все изменяет как адрес вершины стека, так и его содержимое. Например, если записать в стек несколько констант, то обращение за ними из основной программы и из подпрограмм будет разным. Кроме того, если использование стека многократное, нужно позаботиться о непременном восстановлении адреса его вершины после каждого использования, иначе стек может неограниченно расти, и программа перестанет работать.

Как восстановить адрес вершины стека? Проще всего это сделать в основной программе, достаточно записать в SP число 732. При этом по команде останова или по клавише стоп будет гарантирован выход в МСД, если только содержимое стека не менялось. Если же речь идет о восстановлении стека после работы с ним в п/программе, дело сложнее, т.к. иногда трудно определить, через какое число вложенных п/программ мы уже прошли. Лучше всего, на входе в п/программу записать содержимое SP в какую-нибудь ячейку, а на выходе - записать ее содержимое в SP. Кроме того, адрес вершины стека восстанавливают команды
ЕМТ 14
,
HALT
.

Однако, если в стеке были при этом какие-то данные, они могут оказаться потерянными. По причине этих сложностей стек обычно используют только для временного хранения информации, как было показано на примере с сохранением содержимого регистров. Причем, сколько было операторов записи в стек вида:
MOV Rn,-(SP),

Столько же должно быть и операторов извлечения информации из стека вида:
MOV (SP)+,Rn.

Для чего еще может пригодиться стек? Можно использовать те его ячейки, которые заведомо не будут использованы программой, как буферные для хранения переменных или констант. Это довольно широко используется, например, в ассемблерах микро8,9. Причем используются ячейки с адреса 400, т.е. В самом конце стека.
Зная, что в стеке при прерывании сохраняется адрес возврата, можно определить, какое прерывание было. Покажем, как это сделать. Пусть, например, из всех прерываний ЕМТ нам нужно выбрать только ЕМТ 16. Его машинный код=104016.
Вначале изменим вектор ЕМТ на новый, а по этому адресу запишем свою программу обработки прерывания. Что нам нужно? Найти команду, которая вызвала прерывание, и сравнить ее с кодом ЕМТ 16. Если да, то сделать то, что мы хотим, например, выдать содержимое R0 на печать. Если же нет, то передать управление по адресу ЕМТ-диспетчера. Запишем программу обработки прерывания, и прокомментируем ее:

          MOV #мет,@#30 записать новый вектор ЕМТ
          ..........
          ..........
мет: MOV R5,-(SP) сохраняем R5 в стеке.
          MOV 2(SP),R5 извлекаем из стека адрес возврата из прерывания.
          CMP #104016,-(R5) сравниваем код ЕМТ 16 с кодом предшествующей команды,
                                            которая и вызвала прерывание ЕМТ.
         BEQ a если это ЕМТ 16, то к метке а, т.е. Обработать прерывание.
         MOV (SP)+,R5 иначе - восстановить R5,
         JMP @#100112 и передать управление ЕМТ-диспетчеру.
         ..........
         ..........
a:     .......... Программа обработки прерывания ЕМТ 16
         ..........
         ..........

Приведен, конечно, самый простой вариант "вылавливания" ЕМТ 16, пригодный не для любого случая. Отметим, что для того, чтобы написать эту программу, понадобилось знание адреса ЕМТ-диспетчера (100112), для чего проще всего после запуска БК-0010 заглянуть по адресу 30, т.е. Прочитать вектор ЕМТ. Но можно было это сделать и автоматически, для чего в начале программы записать:
MOV @#30,Rn,
а в нужном месте, вместо
JMP @#100112
 
записать JMP @Rn, где Rn - один из регистров.

Категория: Тук-тук, кто в стеке живет? | Автор: ЗАЛЬЦМАН Ю.А., МП-КЛУБ, г.АЛМА-АТА
Просмотров: 1627 | Комментарии: 1 | Рейтинг: 0.0/0 |

Всего комментариев: 0
Имя *:
Email *:
Код *:
Используются технологии uCoz
Форма входа

Поиск
Друзья сайта
Статистика