Вы находитесь на странице: 1из 4

2-1/15.

Гашение незначащих нулей и оптимизация текста программы за счет


сведения нескольких одинаковых таблиц к одной.

Не трудно догадаться, что процедура гашения незначащих нулей должна быть


отработана после завершения отработки процедуры двоично-десятичного
преобразования.
То есть, после того, как в младших полубайтах LEDов, в порядке старшинства,
"залягут" двоично-десятичные числа результата "замера" количества попугаев.
С учетом того, что в самом младшем десятичном разряде, я не стал гасить ноль,
получается следующее:

;================================================================================
; Подпрограмма выбора символов цифр.
;================================================================================
CIFRA addwf PCL,F ; Вычисляемый переход.
goto C_0 ; Символ "0".
goto C_1 ; Символ "1".
goto C_2 ; Символ "2".
goto C_3 ; Символ "3".
goto C_4 ; Символ "4".
goto C_5 ; Символ "5".
goto C_6 ; Символ "6".
goto C_7 ; Символ "7".
goto C_8 ; Символ "8".
goto C_9 ; Символ "9".
goto PROBEL ; "Пробел".
;===============================================================================
.......................................
.......................................

;################################################################################
; Вывод результата "подсчета" количества попугаев на индикацию
; в графический модуль.
;################################################################################
; Задание "координаты", с которой начнется запись байтов данных.
;--------------------------------------------------------------------------------
call STRANICA_5 ; Выбор 5-й страницы.
movlw b'01010000' ; Выбор адреса 17-го столбца (10h).
movwf PortC ; Вывод инструкции "Set Address" в порт С.
call STROB ; Строб под инструкцию.
;---> Возврат по стеку из ПП STROB
;--------------------------------------------------------------------------------
; Группа команд гашения незначащих нулей.
;--------------------------------------------------------------------------------
movf LED5,W ; "Цифирь", из LED5, копируется в W
; (воздействие на Z).
btfss Status,Z ; LED5 =0 или не=0 ?
goto ADMIN ; Если не=0, содержимое LED5 не изменяется
; (гашения нет).
; Если =0, то гашение есть. То есть, в LED5,
movlw .10 ; через W, записывается "прыжковое" число
movwf LED5 ; .10, которое обеспечивает дальнейшее
; исполнение сценария гашения незначащего
; нуля (на индикацию выводится "пробел").
;-------------------------------------
movf LED4,W ;
btfss Status,Z ;
goto ADMIN ; Аналогично, но с "привязкой" к LED4.
movlw .10 ;
movwf LED4 ;
;-------------------------------------
movf LED3,W ;
btfss Status,Z ;
goto ADMIN ; Аналогично, но с "привязкой" к LED3.

1
movlw .10 ;
movwf LED3 ;
;-------------------------------------
movf LED2,W ;
btfss Status,Z ;
goto ADMIN ; Аналогично, но с "привязкой" к LED2.
movlw .10 ;
movwf LED2 ;
;-------------------------------------
movf LED1,W ;
btfss Status,Z ;
goto ADMIN ; Аналогично, но с "привязкой" к LED1.
movlw .10 ;
movwf LED1 ;
;--------------------------------------------------------------------------------
; "Администраторская" подпрограмма.
;--------------------------------------------------------------------------------
ADMIN movf LED5,W ; "Цифирь", из LED5, копируется в W.
call CIFRA ; После этого - "прыжок" в ПП CIFRA.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
.......................................
.......................................

;--------------------------------------------------------------------------------
; Вывод на индикацию "пробела" (применяется при гашении незначащего нуля).
;--------------------------------------------------------------------------------
PROBEL movlw .8 ;
movwf Temp ;
WZ_10 movf Temp,W ;
sublw .8 ; Аналогично, но с "привязкой" к "пробелу".
movwf Reg ;
call Z_10 ;
movwf PortC ;
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;
decfsz Temp,F ;
goto WZ_10 ;
return
;===============================================================================
.......................................
.......................................

;--------------------------------------------------------------------------------
; "Пробел".
;--------------------------------------------------------------------------------
Z_10 movlw high M_10 ;
movwf PCLATH ; Аналогично, но с "привязкой" к "пробелу".
movf Reg,W ;

addwf PCL,F ;
M_10 Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;================================================================================
.......................................
.......................................

Работа процедуры
После отработки ПП BIN2_10, отрабатывается группа команд, "прописанная" как
Задание "координаты", с которой начнется запись байтов данных.
В принципе, если выставить, в ее начале, метку ADMIN, то эту группу команд можно
перенести в конец процедуры гашения незначащих нулей, но я не стал этого делать
по причине того, что смысл надписи ADMIN лучше всего подходит к названию
"администраторской" подпрограммы (на ней и выставил, придав ей "статус"
подпрограммы).
2
К тому же, после этой перестановки, в конечном итоге, в работе устройства ничего
визуально не изменится.
Алгоритм работы группы команд гашения незначащих нулей таков:
Производится анализ наличия/отсутствия нуля в байте текущего LEDа.
Если нуля нет, то рабочая точка программы обходит всю оставшуюся поцедуру
гашения незначащих нулей.
Если ноль есть, то в текущий LED записывается число .10 и происходит "линейный"
переход на обработку следующего LEDа.
В дальнейшем, в части касающейся символьного отображения содержимого LEDа, в
котором предустановлено число .10 (число, определяющее выбор сценария вывода на
индикацию символа "пробел"), будет осуществлен "прыжок" на самый последний
(нижний. Выделен красным цветом) сценарий ПП CIFRA (goto PROBEL).
В соответствии с этим сценарием, на индикацию будет выведен символ "пробел",
представляющий собой 8 "нулевых" байтов (см. ПП ZIFRA, WZ_10 и Z_10).
И все дела …
Короче, символ "пробел" выводится на индикацию точно так же, как и любой из
символов цифр.
По-моему, эта аналогия максимально комфортно способствовует "въезду".
Примечание: команда movf LED...,W (а можно и movf LED...,F) нужна для того,
чтобы воздействовать на флаг Z (см. распечатку команд).
Ну и ладушки. С этим полюбовно покончено.
Но охота продолжается.

Один из элементов "идеальной" оптимизации


Дано: "коровомычащая мать".
Задача: "сделать из нее нечто более стоящее" (хотя бы, частично. "Пупок надрывать"
нужно не абы как, а с умом). В контексте борьбы с "дебилизмом".
Обратите внимание на "нижележащую" картинку:

Вернее, на квадраты, выделенные красным цветом.


Имеет место быть дублирование содержимого страниц графического модуля.
То есть, таблицы вычисляемых переходов, относящиеся ко всем четырем
"вышезакрашенным" страницам, есть абсолютные "клоны" (все "забиты" нулями).
Возникает закономерный вопрос: "А на фиг нужно это избыточное великолепие"?
Возразить на это нечего (правда есть правда. Пусть даже и суровая).
И в самом деле, зачем, в нашем деликатном и тонком деле, нужны аж 4
"крупногабаритных (по 64 "нулевых" байта) дебила"?
Да не нужны они совсем. Достаточно и одного.
Девиденды от этого избавления: как минимум, 64х3=192 команды retlw 0x00, плюс, их
"обслуга".
По-моему, вполне солидно.

3
Что для этого нужно сделать?
Нужно оставить только одну таблицу.
Например, таблицу, обслуживающую 4-ю страницу 1-го кристалла (но можно и
другую, из числа страниц, выделенных красным цветом).
В процессе обработки "нулевого" содержимого остальных 3-х страниц, необходимо
осуществить условный переход в ту ПП, в состав которой входит таблица 4-й
страницы 1-го кристалла.
А именно, в ПП TEXT_4.
Следовательно, ПП TEXT_6, TEXT_10, TEXT_12 можно просто-напросто "выбросить на
помойку".
А это, худо-бедно, а (64+8)х3=216 команд в памяти программ, не считая тех
"волшебных" комбинаций команд, которые можно "убить" за счет того, что директива
end сместится вверх (в данном случае, "программа вообще уйдет" из 2-й страницы
памяти программ).
И текст программы упростится.
После осознания всей "глубины, ширины и высоты этого счастья", с радостным
потиранием ладоней, я реализовал "вышеобозначенное" (дело техники. Самое главное
- понять "откуда ноги растут").
Программа называется 12864_16.asm (прилагается).
В ней, для обеспечения эффективного "отслеживания текущей мысли", я обозначил
крестами (в смысле ++++++) "места залегания усопших" (если Вы не ленивы, то
наткнетесь).
"Некрологи" - там же (можно "поставить свечку").
Два бывших сообщения Message[306] тоже "усопло" (теперь вся программа находится
на 1-й странице памяти программ). Соответствующие "оргвыводы" сделаны.
Кроме того, в этой программе используется "вышеобозначенное" гашение незначащих
нулей ("двух зайцев ухлопал". Уже есть чем закусить).
Принципиальная схема - та же.
А теперь сравните количество команд программы 12864_15.asm (2176, без гашения
незначащих нулей) и программы 12864_16.asm (2005, с гашением).
Выводы делайте сами.

"Практикум по конструированию устройств на PIC контроллерах"      http://ikarab.narod.ru       E-mail: karabea@lipetsk.ru