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

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

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

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

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

Исследование команды вызова подпрограммы и возврата из нее

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

1. Цель работы

Изучить и исследовать методы использования стека, обращения к подпрограммам и возврата из них, которые используются в микроконтроллерах семейства МК51.

2. Основные теоретические сведения

Откройте МУ к лабораторной работе №13 и вспомните основные теоретические сведения по организации стековой памяти. При вызове подпрограммы в стек записывается содержимое программного счетчика (счетчика команд) PC, который содержит в этот момент адрес команды, следующей за командой вызова подпрограммы. Адрес команды – это 16-разрядное (двухбайтное число), поэтому вначале в стек загружается младший байт счетчика PCL, а затем – старший байт PCH. Указатель стека SP при этом дважды инкрементируется.

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

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

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

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

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

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

3.1. Исследование команды вызова подпрограммы и возврата из нее

При записи программы на языке Ассемблера для вызова подпрограммы используется команда с мнемоникой CALL label, где label – это метка, соответствующая первой команде подпрограммы. Обычно имя этой метки соответствует имени (названию) подпрограммы. Возврат из подпрограммы выполняется по команде RET. Эти команды являются безусловными.

3.1.1. Создайте в Вашей папке файл с именем count.asm и запишите в него текст программы, которая определяет количество единиц в ячейке памяти данных. Адрес ячейки вводится из порта P1, а результат подсчета выводится в порт P2. Процедура определения количества единиц в байте осуществляется подпрограммой с именем BYTE, алгоритм которой аналогичен программе из п.3.2.3 лабораторной работы № 7. В подпрограмме используется регистр R0 для передачи входного параметра – адреса ячейки памяти данных, из которой берется байт для анализа. Выходной параметр подпрограммы – это регистр R1, в котором находится подсчитанное число единиц.

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

MOV P2, #0 ; Вывести нули в порт P2

MOV R0, P1 ; Ввод адреса байта из порта P1

CALL BYTE ; Вызов подпрограммы подсчета единиц в байте

MOV P2, R1 ; Вывод количества единиц в порт P2

JMP $ ; Зацикливание программы

 BYTE - подпрограмма подсчета единиц в байте

 Входной параметр регистр R0 – адрес байта в ПД

 Выходной параметр регистр R1 – количество единиц в байте

BYTE: MOV R7, #8 ; Загрузить счетчик разрядов байта

MOV R1, #0 ; Очистить счетчик единиц

MOV A, @R0 ; Пересылка байта в аккумулятор

CLR C

SHIFT: RRC A ; Сдвиг байта вправо через перенос

JNC MET1 ; Переход, если C=0

INC R1 ; Инкремент счетчика единиц

MET1: DJNZ R7, SHIFT ; Цикл сдвига, если (R7)  0

RET ; Возврат из подпрограммы

END ; Конец текста программы

Получите файлы count.obj и count.hex. Запустите симулятор AVSIM51 и загрузите в него файл для отладки. Перед выполнением программы запишите на вход порта P1 адрес ячейки ПД, где будет анализируемый байт (произвольное число в диапазоне от 08H до 37H). Затем занесите по указанному адресу произвольное число в ячейку ПД. Например, на входе порта запишите 20H, а в ячейку с адресом 0020H (дамп 2 на экране) занесите число 55H = 01010101.

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

3.1.2. Часто подпрограммы используют те же регистры, что и основная программа. Поэтому необходимо сохранять содержимое регистров основной программы на время работы подпрограммы. Можно сохранять регистры в стеке при входе в подпрограмму, а затем восстанавливать их содержимое перед выходом из подпрограммы. Однако, часто более удобным и коротким способом сохранения регистров является переключение банков регистров на время выполнения подпрограммы.

Рассмотрим программу, которая заполняет массив ячеек памяти данных константой, а затем подсчитывает контрольную сумму этого массива. Адрес начала массива вводится из порта P0, количество элементов (ячеек) массива вводится из порта P1, а значение константы – из порта P2. Результат работы программы – контрольная сумма выводится в порт P3. Основная программа использует регистры банка 0. Процедуру заполнения ячеек массива константой необходимо оформить как подпрограмму, которая использует регистры 1-го банка. После заполнения всех ячеек константой подпрограмма должна установить флаг F0. Подсчет контрольной суммы массива также необходимо оформить в виде подпрограммы, которая использует регистры 2-го банка. После выполнения всех указанных действий основная программа должна зациклиться.

Создайте в Вашей папке файл с именем check.asm и занесите в него текст программы

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

MOV P3, #0 ; Вывести нули в порт P3

MOV R0, P0 ; Ввод из порта P0 начального адреса массива

MOV R1, P1 ; Ввод из порта P1 количества элементов массива

MOV R2, P2 ; Ввод из порта P2 значения константы

CLR F0 ; Сбросить флаг F0

CALL FILL ; Вызов подпрограммы заполнения массива константой

CALL SUM ; Вызов подпрограммы подсчета контрольной суммы

MOV P3, A ; Вывод контрольной суммы в порт P3

JMP $ ; Зацикливание основной программы

; FILL – подпрограмма заполнения массива ячеек ПД константой

 Входные параметры ячейка с адресом 00H – начальный адрес массива

 ячейка с адресом 01H – количество элементов

 ячейка с адресом 02H – значение константы

 Выходной параметр флаг F0 – равен единице, если заполнение массива выполнено

 Используется 1-й банк РОН

FILL: SETB RS0 ; Выбрать 1-й банк РОН

MOV R0, 00H ; Загрузить указатель адреса ячеек

MOV R7, 01H ; Загрузить счетчик элементов массива

LOOP: MOV @R0, 02H ; Пересылка константы в ячейку массива

INC R0 ; Адрес следующего элемента

DJNZ R7, LOOP ; Цикл записи, если (R7)  0

SETB F0 ; Установить F0=1

CLR RS0 ; Переход в 0-й банк РОН

RET  Возврат из подпрограммы

; SUM – подпрограмма подсчета контрольной суммы массива ячеек ПД

 Входные параметры ячейка с адресом 00H – начальный адрес массива

 ячейка с адресом 01H – количество элементов

 Выходной параметр регистр A – контрольная сумма массива

 Используется 2-й банк РОН

SUM: SETB RS1 ; Выбор 2-го банка РОН

MOV R0, 00H ; Загрузить указатель адреса

MOV R7, 01H ; Загрузить счетчик элементов

CLR A ; Очистить аккумулятор

CYCLE: ADD A, @R0 ; Суммирование аккумулятора с содержимым ячейки

INC R0 ; Адрес очередного элемента массива

DJNZ R7, CYCLE ; Цикл суммирования, если (R7)  0

CLR RS1 ; Переход в 0-й банк РОН

RET  Возврат из подпрограммы

END ; Конец текста программы

Получите файлы check.obj и check.hex. Запустите симулятор и загрузите в него файл для отладки. Перед выполнением программы отключите отображение меток и занесите исходные данные на входы портов. Адреса ячеек массива ПД – в диапазоне от 20H до 37H. Количество элементов в массиве – от 04H до 08H, а значение константы – 01H до FFH. Выполните программу в пошаговом режиме, наблюдая за переключением банков регистров (по значениям в RB), регистра-указателя стека и областью стека, а также ячейками памяти данных. Следите за выполнением каждой команды программы – это очень важно! Убедитесь в правильности работы программы. Затем осуществите прогон программы в автоматическом режиме, задав новые исходные данные.

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