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

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

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

2.1. Создайте в Вашей папке файл с именем count.asm и запишите в него текст программы, которая определяет количество единиц в ячейке памяти данных. Адрес ячейки вводится из порта P1, а результат подсчета выводится в порт P2. Процедура определения количества единиц в байте осуществляется подпрограммой с именем BYTE. В подпрограмме используется регистр 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.

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

2.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), регистра-указателя стека и областью стека, а также ячейками памяти данных. Следите за выполнением каждой команды программы – это очень важно! Убедитесь в правильности работы программы. Затем осуществите прогон программы в автоматическом режиме, задав новые исходные данные.

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