Заметки на полях
Традиционная область использования команд двоично-десятичной коррекции, в том числе и в процессорах
В области BCD-преобразований есть три основные задачи:
• Преобразование двоичного/шестнадцатеричного числа в упакованный BCD-формат.
• Распаковка упакованного BCD-формата для непосредственного представления десятичных чисел с целью их вывода на дисплей.
• Обратное преобразование упакованного BCD-формата в двоичный/шестнадцатеричный для выполнения над ним, например, арифметических действий.
Некоторые процедуры для этой цели приведены в фирменной Application notes 204. При их использовании нужно учесть ряд моментов. Так, процедура bin2BCD8 для преобразования однобайтового числа в BCD работает только для чисел от 0 до 99 (для больших чисел нужен еще один байт, точнее, тетрада — в ней будет храниться старший разряд). В «аппноте» процедура представлена в универсальном виде, пригодном (при небольшой модификации) и для получения упакованного BCD, и для изначально распакованного (результат в двух отдельных байтах). Чтобы не путаться, приведу здесь ее вариант (листинг 15.3), который заодно более экономичный по количеству используемых регистров. Исходное hex-число содержится в регистре temp, распакованный результат — в temp1: temp. Как и в предыдущих случаях, комментарии сохранены из исходного текста.
;преобразование 8-разрядного hex в неупакованный BCD
;вход hex= temp, выход BCD temp1-старший; temp — младший
;эта процедура работает только для исходного hex от 0 до 99
bin2bcd8:
clr temp1 ;clear result MSD
bBCD8_1: subi temp,10 ;input = input — 10
brcs bBCD8_2 ;abort if carry set
inc temp1 ;inc MSD
rjmp bBCD8_1 ;loop again
bBCD8_2:subi temp, — 10 ;compensate extra subtraction
ret
В листинге 15.4 приведено одно из решений обратной задачи — преобразования упакованного BCD (например, тех же значений часов, минут и секунд из RTC) в hex-число, после чего с ним можно производить арифметические действия. По сравнению с «фирменной» BCD2bin8 эта процедура хоть и немного длиннее, но понятнее и более предсказуема по времени выполнения («фирменная» может занимать от 3 до 48 тактов).
;на входе в temp упакованное BCD-значение
;на выходе в temp hex-значение
;temp1 — вспомогательный регистр для промежуточного хранения temp
;действительна только для семейства Меgа
HEX_BCD:
mov temp1, temp
andi temp, 0b11110000 ; распаковываем — старший
swap temp ;старший в младшей тетраде
mul temp,mult10 ;умножаем на 10, в r0 результат умножения
mov temp,temp1 ;возвращаемся к исходному
andi temp,0b00001111 ;младший
add temp,r0 ;получили hex
ret