Сергей, вот оптимизированный вариант:
; -----------------------------------------------------
bin2bcd:
; -----------------------------------------------------
; Преобразование однобайтного числа в распакованный BCD
; -----------------------------------------------------
; Вход : R16 - число от 0 до 255
; Выход: R18:17:16 - BCD представление
; Изменяет: SREG
; -----------------------------------------------------
ldi R17, 0xFF ; инициализация десятков и
ldi R18, 0xFF ; сотен значением -1
hundreds:
inc R18 ; увеличиваем сотни
subi R16, 100 ; вычитаем 100 из исходного
brcc hundreds ; если было > 100 - повторяем
subi R16, 256-100 ; компенсация лишнего вычитания
tens:
inc R17 ; увеличиваем десятки
subi R16, 10 ; вычитаем 10 из исходного
brcc tens ; если было > 10 - повторяем
subi R16, 256-10 ; компенсация лишнего вычитания
ret
В случае 8-битного числа этот способ самый быстрый. Для преобразования больших чисел, особенно на 8-битных процессорах может быть эффективнее метод под названием "Double dabble". Метод дает упакованный BCD (4 бита на цифру). Суть его в следующем: создается область памяти такого размера в битах, чтобы вместить и исходное число, и результат. Рассмотрим пример для 8-битного числа. Достаточно 20 бит (8 + 3*4). В младшие биты размещается исходное число, старшие инициализируем нулями - в них будет результат. Затем в цикле выполняем следующее :
проверяем все цифры результата (группы по 4 бита). Те из них, которые больше 4, увеличиваем на 3. Затем сдвигаем всю область памяти влево на 1 разряд.
Цикл повторяем 8 раз (сколько было бит в исходном числе). Потом забираем результат из старших разрядов. Пример кода:
; -----------------------------------------------------
bin2bcd2:
; -----------------------------------------------------
; Преобразование однобайтного числа в упакованный BCD
; -----------------------------------------------------
; Вход : R24 - число от 0 до 255
; Выход: R17:16 - BCD представление
; Изменяет: R18, R24, SREG
; -----------------------------------------------------
ldi R16, 0 ; инициализация результата
ldi R17, 0 ;
ldi R18, 8 ; счетчик циклов
loop:
cpi R16, 0x05 ; сравнение разряда 0
brhs L1 ; если <= 4, продолжаем
subi R16, 256-3 ; иначе увеличиваем разряд 0 на 3
L1:
cpi R16, 0x50 ; сравнение разряда 1
brcs L2 ; если <= 4,
subi R16, 256-(3*16); иначе увеличиваем разряд 1 на 3
L2:
cpi R17, 0x05 ; сравнение разряда 2
brhs L3 ; если <= 4, продолжаем
subi R17, -3 ; иначе, увеличиваем разряд 2 на 3
L3:
lsl R24 ; сдвиг
rol R16
rol R17
dec R18 ; цикл
brne loop
ret