приводимые мною “способы” совершенно бесполезны, но
они показывают, что отключать собственную фанта-
уверяю вас - они могут пригодиться! Во всяком случае,
зию никогда не следует ©.
Вызов подпрограммы без CALL.
Можно применить следующий код:
; аналог команды CALL Subroutine
--------------
:-----------------1
"РЛ"-НАЧИНАЮ Щ ИМ
о
-------------------------------
mov
DPTR, #ret_ptr
push
DPL
push
DPH
jmp
Subroutine
; вызов подпрограммы Subroutine
ret_ptr:
Этот код интересен тем, что между занесением в стек адреса возврата ret_ptr и фактическим переходом к
подпрограмме может быть сколько угодно команд, т.е. процесс вызова подпрограммы как бы размазывается
по тексту. Кроме того, этот прием может заставить подпрограмму “возвращать” управление в любую точку
программы ©.
Возврат из подпрограммы без RET.
; аналог команды RET
pop
DPH
pop
DPL
clr
A
jmp
@A+DPTR
Не смотря на кажущуюся бесполезность приведен-
ных примеров, применять их порой очень удобно, а по-
рой необходимо. Если вы используете в своем устрой-
стве внешнее ОЗУ большого объема, то можно пере-
нести область программного стека из внутреннего
ОЗУ во внешнее. Тут-то как раз и придется использо-
вать вызов и возврат из подпрограмм без примене-
ния специальных команд. Нужно будет создать спе-
циальные макросы для вызова подпрограммы и воз-
врата из нее, которые будут использовать внешнее
ОЗУ для хранения адреса возврата. Этот прием по-
зволяет получить дополнительное свободное про-
странство внутреннего ОЗУ и использовать многократ-
ный вызов подпрограмм друг из друга, не опасаясь
переполнения стека (правда, при существенном сни-
жении производительности).
Небольшое примечание. Языки высокого уровня
обычно имеют встроенные средства для перемещения
стека во внешнее ОЗУ, но, как вы понимаете, ничто не
мешает использовать эту возможность и на ассембле-
ре. Следует только помнить, что обработка прерыва-
ний все-таки будет использовать стек во внутреннем
ОЗУ, т.к. невозможно “подменить" аппаратно реализо-
ванный вызов подпрограммы обработчика прерывания.
Но глубина такого стека явно будет невелика и с дос-
таточной точностью предсказуема.
Другой пример: очень часто при разработке инте-
рактивных программ требуется осуществлять вывод
какой-либо текстовой информации на дисплей или
иное устройство символьного вывода. Как правило,
сами текстовые строки размещаются в виде констант
в сегменте кода, например так:
Strl:
DB
'Первая строка',
О
Str2:
DB
'Вторая строка',
О
Для вывода строки создается отдельная подпрограм-
ма, которая последовательно выводит все символы стро-
ки, пока не встретит код символа “ноль”, которым обозна-
чается конец строки. Остается только решить, как сооб-
щать подпрограмме, какую именно строку следует выво-
дить, т.е. решить вопрос передачи параметров в подпрог-
рамму. Можно применять следующий традиционный код:
MOV
DPTR,
# s trl
CALL
Output
MOV
DPTR, #Str2
CALL
Output
При этом подразумевается, что подпрограмма
Output использует в качестве параметра адрес стро-
ки, помещенный в DPTR:
Output:
; подпрограмма вывода строки
clr
А
move
A, ©A+DPTR
; получаем очередной символ из строки
jz
exit_output
; если конец - выход из подпрограммы
; тут выводим очередной символ строки на устройство отображения
inc
DPTR
; вычисляем адрес следующего символа
jmp
Output
; повторяем цикл вывода
exit_output:
ret
40
У Радиолюбитель - 0 3 /2 0 0 8
предыдущая страница 40 Радиолюбитель 2008-03 читать онлайн следующая страница 42 Радиолюбитель 2008-03 читать онлайн Домой Выключить/включить текст