Структура ПЗУ компьютера ЛамПанель
ПЗУ компьютера ЛамПанель представляет из себя текстовый файл, хранящийся в папке программы с именем lampanel.rom
Открыть и просмотреть его можно с помощью стандартного Блокнота.
Поэтому такое ПЗУ возможно изменять.
Если требуется добавить новую подпрограмму в ПЗУ, нужно сохранить её в специальном формате *.rom с помощью кнопки . Затем текст программы просто добавляется в конец файла lampanel.rom.
Вызов подпрограмм
Это достаточно сложная операция для процессора, поскольку для этого нужно:
запомнить адрес возврата – адрес команды, на которую нужно перейти после завершения подпрограммы;
передать параметры в подпрограмму;
разместить в памяти локальные переменные подпрограммы;
для подпрограммы- функции: передать в вызывающую программу результаты работы;
обеспечить возврат из подпрограммы по правильному адресу.
Стек
Важнейшую роль в решении выше означенных задач играет стек (от англ. stack–кипа, стопка) – специальная область оперативной памяти, в которой хранятся адреса возврата из подпрограмм и локальные переменные.
Если попытаться визуализировать для себя эту динамическую структуру данных, то можно, например, представить банку, в которую кладут шары. Положить шар можно только сверху и достать только верхний.
В ЛамПанели стек размещается в оперативной памяти вместе с программой и данными. Оперативная память имеет размер 256 байт, адреса ячеек памяти изменяются от 0 до 255 (FF16). Стек находится в самом конце оперативной памяти и “растёт вверх”. Таким образом, первое записанное в стек машинное слово будет иметь адрес FE16 и занимать байты с адресами, соответственно, FE16и FF16. И так далее “вверх”.
Для управления стеком в процессоре есть специальный регистр SP (stackpointer–указатель стека), в котором хранится адрес вершины стека.
При запуске программы в регистр SPзаписывается значение 10016=25610. Этот адрес находится за пределами оперативной памяти и говорит о том, что стек пуст.
При добавлении в стек первого значения указатель стека уменьшается на 2 (до FE16), а потом по этому адресу записывается число.
Для записи значения в стек используется оператор PUSH (от англ. push–втолкнуть).
Рассмотрим пример записи значения в стек.
Пример:
mov1234, R0; | запись значения 123416в регистр R0 |
push R0; | запись содержимого регистра R0 в стек |
После выполнения команды PUSH значение регистра SPстало равно FE16, и теперь он указывает на последнее слово в памяти, в котором записано число 123416 – значение регистра R0.
Для извлечения значения из стека используется оператор POP (от англ. pop–хлопнуть, вытолкнуть), который “снимает” значение с вершины стека и записывает его в назначенный регистр.
Добавим его в нашу программу и просмотрим ход исполнения.
Пример:
mov1234, R0; | запись значения 123416в регистр R0 |
push R0; | запись содержимого регистра R0 в стек |
pop R1; | извлечение значения из стека и запись его в регистр R1 |
После выполнения программы можно пронаблюдать следующее:
· в регистре R1 находится то же значение 123416, что и в регистре R0;
· регистр SPсодержит значение 10016, которое говорит о том, что стек пуст;
· в последних двух байтах оперативной памяти осталось значение 123416, однако оно уже не является частью самого стека, поскольку адрес в регистре SPизменен.
Создание и вызов подпрограммы
Рассмотрим эти процессы на примере подпрограммы, которая возводит содержимое регистра R0 в квадрат.
Данная подпрограмма будет содержать всего одну команду:
mulR0, R0
В начале подпрограммы необходимо поставить метку, которая соответствует имениподпрограммы, а в конце – оператор возврата RET (от англ. return–возврат), по которому процессор возвращается к точке вызова.
Тогда вся подпрограмма будет выглядеть следующим образом:
SQR:
mulR0, R0
ret
Опишем своеобразный паспорт этой подпрограммы.
Имя: SQR.
Входные данные: число в регистре R0.
Выходные данные: квадрат числа в регистре R0.
Сама подпрограмма размещается в оперативной памяти, а значит, её код нужно расположить вне основной программы, за оператором STOP.
Для вызова подпрограммы используется оператор вызова CALL (от англ. call–вызывать, звонить), после которого записывается имя подпрограммы, или иными словами, метка, с которой начинается подпрограмма, то есть адрес точки входа.
Рассмотрим всю программу полностью.
Пример:
mov19, R0; | R0:=1916 |
call SQR; | вызов подпрограммы SQR |
stop; | останов основной программы |
SQR:; | адрес точки входа в подпрограмму SQR |
mul R0, R0; | R0:=R0*R0 |
ret; | возврат из подпрограммы |