Однокристальные микроконтроллеры семейства MCS-51
Лабораторная работа № 8
Подпрограммы и стек
1. Цель работы
Изучить и исследовать методы использования стека, обращения к подпрограммам и возврата из них, которые используются в микроконтроллерах семейства МК51.
2. Основные теоретические сведения
Стек – это область памяти данных микроконтроллера, адресация к ячейкам которой производится с помощью специального регистра – указателя стека SP. Работа стека организована по принципу регистровой памяти LIFO, т.е. число, записанное в стек последним, извлекается из него первым. Стек используется для организации обращения к подпрограммам и при обработке прерываний, может быть использован для передачи параметров подпрограммам и для временного хранения содержимого регистров общего назначения и специальных функций.
Стек может располагаться в любом месте внутренней памяти данных. По сигналу сброса (начальной установки) в указатель стека SP заносится значение 07H. Это сделано для совместимости микроконтроллеров семейства МК51 с ранее разработанным семейством МК48. Однако, при этом стек будет занимать область банков 1, 2 и 3 регистров общего назначения, что ограничивает возможности микроконтроллера. Поэтому обычно после сброса программа переопределяет местоположение стека, который удобно разместить по адресам от 60H до 7FH. Для переопределения стека необходимо выполнить команду MOV SP, #d , где d – число, определяющее адрес вершины стека, т.е. его нижнюю границу. Например, если мы желаем расположить стек с адреса 60H памяти данных, то необходимо выполнить команду инициализации стека вида:
MOV SP, #60H
Механизм доступа к стеку в МК51 следующий: перед загрузкой в стек содержимое регистра-указателя стека SP инкрементируется, а после извлечения из стека – декрементируется. В МК51 имеются две команды операций со стеком:
PUSH ad ; (SP) ß (SP) + 1, ((SP)) ß ad - Загрузка (запись) в стек
POP ad ; (ad) ß ((SP)), (SP) ß (SP) – 1 Извлечение (чтение) из стека
Здесь обозначено: ad - это прямой адрес ячейки памяти данных или регистра специальных функций. Следует отметить, что в случае регистров специальных функций более удобно использовать не действительные адреса, а их символические имена.
Рассмотрим процесс загрузки в стек. Допустим, что в исходном состоянии в указателе стека будет (SP) = 60H. Нужно сохранить в стеке содержимое аккумулятора, регистра состояния PSW и регистра указателя данных DPTR. Загрузку в стек этих регистров можно выполнить последовательностью следующих команд:
PUSH ACC ; Загрузить в стек содержимое аккумулятора
PUSH PSW ; Загрузить в стек содержимое регистра PSW
PUSH DPL ; Загрузить в стек младший байт регистра DPTR
PUSH DPH ; Загрузить в стек старший байт регистра DPTR
Обратите внимание, что при загрузке в стек содержимого аккумулятора использовано его имя ACC как регистра специальных функций. Это необходимо обязательно учитывать!
Стек после выполнения этих команд будет выглядеть следующим образом:
Память данных
64H |
DPH |
ß Вершина стека (новое значение) |
63H |
DPL |
|
62H |
PSW |
|
61H |
ACC |
|
60H |
xxxx xxxx |
ß Вершина стека (исходное значение) |
5FH |
В указателе стека будет (SP) = 64H. Это новая вершина стека.
Извлечение из стека содержимого регистров должно выполняться в обратном порядке последовательностью команд:
POP DPH ; Извлечь из стека содержимое регистра DPH
POP DPL ; Извлечь из стека содержимое регистра DPL
POP PSW ; Извлечь из стека содержимое регистра PSW
POP ACC ; Извлечь из стека содержимое аккумулятора
Стек после выполнения этих команд будет выглядеть следующим образом:
Память данных
64H |
DPH |
ß Вершина стека (старое значение) |
63H |
DPL |
|
62H |
PSW |
|
61H |
ACC |
|
60H |
xxxx xxxx |
ß Вершина стека (новое значение) |
5FH |
В указателе стека вновь будет (SP) = 60H. Обратите внимание, что после извлечения из стека в нем сохранились записанные ранее значения, однако использовать их при адресации через SP сложно (нужно задавать вершину стека для извлечения данных, что нарушает логику работы стека).
При вызове подпрограммы в стек записывается содержимое программного счетчика (счетчика команд) PC, который содержит в этот момент адрес команды, следующей за командой вызова подпрограммы. Адрес команды – это 16-разрядное (двухбайтное число), поэтому вначале в стек загружается младший байт счетчика PCL, а затем – старший байт PCH. Указатель стека SP при этом дважды инкрементируется.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.