PIC16. Ассемблер. Оптимизация последовательности условного ветвления
Влад Князев
1 апреля 2004
В системе команд данного семейства, команда сравнения двух чисел отсутствует. В качестве инструкций сравнения используются либо инструкция вычитания sublw, либо инструкция «Исключающее ИЛИ» xorlw. Последнюю инструкцию особенно удобно использовать при проверке условий «равно» / «не равно».
В тех случаях, когда требуется организация условного ветвления в программах по значению некоторой переменной, операция xorlw дает возможность несколько сократить код при последовательном сравнении переменной с элементами из некоторого набора констант.
Пусть мы имеем некоторый фрагмент такого кода:
call GetChr ; Ввод данных с клавиатуры,
; результат в регистре W
; и в переменной KeyBuf
xorlw 'F' ; Выбор текущего пункта меню?
bz DoItem ; Да, выполнить обработку
movfw KeyBuf ; Выбор следующего пункта? #####
xorlw '+' ;
bz NextItem ; Переход, если ДА
movfw KeyBuf ; Выбор предыдущего пункта? #####
xorlw '-' ;
bnz menu_loop ; Переход, если НЕТ –
; все остальные кнопки игнорировать
Инструкции перезагрузки рабочего регистра W (обозначено ##### в комментариях) в данном случае не является необходимой и их можно удалить при соответствующей модификации кода:
call GetChr ; Ввод данных с клавиатуры,
; результат в регистре W
xorlw 'F' ; Выбор текущего пункта меню?
bz DoItem ; Да, выполнить обработку
xorlw '+' ^ 'F' ; Выбор следующего пункта?
bz NextItem ; Переход, если ДА
xorlw '-' ^ '+' ; Выбор предыдущего пункта?
bnz menu_loop ; Переход, если НЕТ –
; все остальные кнопки игнорировать
Как видим, фрагмент кода сократился на две инструкции и, кроме того, освободилась ячейка регистрового файла, что также в ряде случаев может быть необходимо. Здесь в соответствии с синтаксисом ассемблера для обозначения операции «Исключающее ИЛИ» используется символ ^.
Чтобы понять, как такая оптимизация работает, нужно вспомнить некоторые свойства логической функции «Исключающее ИЛИ»:
x ^ x = 0;
x ^ y = y ^ x,
т.е. «Исключающее ИЛИ» является коммутативной функцией;
x ^ y ^ z = (x ^ y) ^ z = x ^ (y ^ z),
т.е. «Исключающее ИЛИ» является ассоциативной функцией.
Из этих свойств следует, что в нашем случае
результат первого сравнения
W = W ^ 'F';
результат второго сравнения
W = W ^ ('+' ^ 'F') = W ^ 'F' ^ '+' ^ 'F' = W ^ '+';
результат третьего сравнения
W = W ^ ('-' ^ '+') = W ^ '+' ^ '-' ^ '+' = W ^ '-'.