Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР_13.doc
Скачиваний:
1
Добавлен:
27.09.2019
Размер:
74.75 Кб
Скачать

МИНИСТЕРСТВО ОБРАЗОВАНИЯ РЕСПУБЛИКИ БЕЛАРУСЬ

ГОМЕЛЬСКИЙ ГОСУДАРСТВЕННЫЙ ДОРОЖНО-СТРОИТЕЛЬНЫЙ КОЛЛЕДЖ имени Ленинского комсомола

Методические указания по выполнению лабораторных работ по дисциплине «ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ»

Лабораторная работа № 13

Использование стековой памяти при написании программ

ГГДСК Гомель 2011

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 при этом дважды инкрементируется.

При возврате из подпрограммы в счетчик команд из стека записывается адрес возврата. Сначала извлекается старший байт PCH, а затем – младший байт PCL. Указатель стека при этом дважды декрементируется.

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

Для успешной работы любой подпрограммы необходимо однозначно определить способ передачи в нее исходных данных и способ вывода результатов ее работы. Подпрограмма, которой требуется дополнительная информация в виде параметров ее настройки или операндов, называется параметризуемой. Примером параметризуемой программы может служить подпрограмма временной задержки, если основной программе требуется реализация временных задержек различной длительности. Основная программа при этом должна обеспечить передачу в подпрограмму уставок, обеспечивающих требуемое время задержки.

Получили распространение три способа передачи параметров: через память, через регистры общего назначения и через область флагов.

При передаче входных параметров через память основная программа обязательно содержит команды загрузки некоторых ячеек памяти, а подпрограмма – команды считывания из этих ячеек. При передаче выходных параметров подпрограмма должна загрузить некоторые ячейки памяти, а основная программа – считать. Передача параметров через регистры осуществляется аналогичным образом. В третьем способе используются флаги C и F0, сохраняемые в регистре состояния PSW, либо флаги пользователя (128 флагов) из области прямоадресуемых битов памяти данных (адреса ячеек 20H…2FH).

3. Порядок выполнения работы

3.1. Исследование команд загрузки и извлечения из стека

3.1.1. Запустите симулятор/отладчик AVSIM51, отключите отображение меток и запишите в память программу загрузки в стек содержимого регистров микроконтроллера A, B и DPTR:

MOV SP, #38H  Определить стек

PUSH ACC  Загрузить в стек содержимое аккумулятора

PUSH B  Загрузить в стек содержимое регистра B

PUSH DPL  Загрузить в стек младший байт регистра DPTR

PUSH DPH  Загрузить в стек старший байт регистра DPTR

NOP

Задайте содержимое регистров (A) = AAH, (B) = BBH, (DPTR) = 2211H. Выполните программу в пошаговом режиме, наблюдая за изменением указателя стека SP и содержимого ячеек стека (нижний дамп памяти данных). Содержимое стека отобразите по форме

Область стека

Адрес

Содержимое

Значение SP

SP= (Конечное значение)

SP=

SP=

SP= (Исходное значение)

Укажите на рисунке, как разместились в стеке содержимое регистров A, B, DPTR.

3.1.2. Запишите в память симулятора программу восстановления содержимого регистров (извлечения из стека)

POP DPH  Извлечь из стека содержимое старшего байта регистра DPTR

POP DPL  Извлечь из стека содержимое младшего байта регистра DPTR

POP B ; Извлечь из стека содержимое регистра B

POP ACC ; Извлечь из стека содержимое аккумулятора

NOP

Перед выполнением этой программы очистите регистры A, B и DPTR, записав в них нули.

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

3.1.3. Часто при вызове подпрограмм требуется запомнить содержимое регистров общего назначения, которые использовала основная программа. Затем, при возврате из подпрограммы надо восстановить содержимое этих регистров. Для этой цели удобно использовать стек. Однако следует помнить, что в командах обращения к стеку нужно использовать прямой адрес регистра общего назначения в памяти данных, а не его имя R0, R1,…,R7. При этом надо учитывать, в каком регистровом банке находятся эти регистры. Например, адрес регистра R0 в банке 0 будет 00H, адрес этого же регистра в банке 1 будет 08H, а в банке 3 – 18H.

Запишите в память симулятора программу сохранения в стеке содержимого регистров R1, R2, R7 0-го банка

PUSH 01H ; Загрузить в стек содержимое регистра R1

PUSH 02H ; Загрузить в стек содержимое регистра R2

PUSH 07H ; Загрузить в стек содержимое регистра R7

NOP

Перед выполнением программы занесите в ячейки памяти данных с адресами 01H, 02H и 07H, соответствующие регистрам R1, R2 и R7 0-го банка, произвольные значения, например, 01H, 02H, 07H.

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

Занесите в память симулятора программу восстановления содержимого регистров R1, R2 и R7 0-го банка

POP 07H ; Извлечь из стека содержимое регистра R7

POP 02H ; Извлечь из стека содержимое регистра R2

POP 01H ; Извлечь из стека содержимое регистра R1

NOP

Перед выполнением программы очистите ячейки памяти данных с адресами 01H, 02H и 07H, соответствующие регистрам R1, R2 и R7 0-го банка.

Выполните программу восстановления содержимого регистров в пошаговом режиме, наблюдая за ячейками памяти данных, соответствующими этим регистрам.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]