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-го банка.
Выполните программу восстановления содержимого регистров в пошаговом режиме, наблюдая за ячейками памяти данных, соответствующими этим регистрам.
3.2. Исследование команды вызова подпрограммы и возврата из нее
При записи программы на языке Ассемблера для вызова подпрограммы используется команда с мнемоникой CALL label, где label – это метка, соответствующая первой команде подпрограммы. Обычно имя этой метки соответствует имени (названию) подпрограммы. Возврат из подпрограммы выполняется по команде RET. Эти команды являются безусловными.
3.2.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 ; Конец текста программы
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.