[an error occurred while processing this directive]
Возвращаясь к теме урезанных sprintf
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено BLACKEAGLE 24 декабря 2002 г. 01:37

Перетряхиваю вот свои библиотеки для х51 и АВР, и по ходу совершенствую некоторые тяжеловесные функции, к которым относятся, разумеется, и itoa/ltoa. Стало интересно узнать - кто какие применяет НЕСТАНДАРТНЫЕ приемы при преобразовании ulong/long/uint/int в ASCII/BCD?

С 16-битниками обычно все проще - практически все имеют команды div 32/16=16.16, посредством которых всё делается просто и достаточно быстро - дели себе на степени 10 и радуйся. А вот с 8-битниками такого не сделать, приходится изгиляться, лепить длинные таблицы и т.д. Особенно это актуально для АВР, в котором нет div. Думаю, соображения по subj будет интересно услышать многим. Вот, к примеру, мой способ/вариант быстрого itoa для х51 - в псевдокоде, т.к. асм-текст длинный и нудный:


//int=FF FF для примера
bcd0=bcd1=bcd2=0
a=high_byte
jz convert_low_byte
a=high_nibble_of_high_byte //0fh=15
jz convert_low_nibble_of_high_byte
a=a*3 //таблица из 15 элементов по 3 байта
bcd0=hitable[a+2] //15-й элемент таблицы=06h 14h 40h, т.е. bcd-представление F000h
bcd1=hitable[a+1]
bcd2=hitable[a+0] //bcd210=061440h, т.е. = F000h


convert_low_nibble_of_high_byte:
a=low_nibble_of_high_byte //0fh=15
jz convert_low_byte
a=a*2 //таблица из 15 элементов по 2 байта
bcd0=da(bcd0+hitable[a+1]) //15-й элемент таблицы=38h 40h, т.е. bcd-представление 0F00h. DA=команда decimal adjust
bcd1=da(bcd1+hitable[a+0])+carry
bcd2=bcd2+carry //bcd2:1:0=065280h, т.е. = FF00h


convert_low_byte:
a=low_byte //FFh=255
jz all_done
b=100
div ab //a=сотни=2, b=остаток=55
temp=a //temp=сотни=2


convert_low_nibble:
a=b //55(dec)
b=10
div ab //a=десятки=5, b=единицы=5
swap a
orl a,b //a=55h
bcd0=da(bcd0+a)
bcd1=da(bcd1+temp+carry)
bcd2=bcd2+carry //для bcd2 da не нужно, т.к. bcd2 всегда меньше или равно 6


all_done:
ret

Это дело выполняется в худшем случае за 115 тактов, т.е. за 4.6 мкс на 25-МГц Cygnal. Занимает достаточно много, т.к. всё без циклов (inline), но цель была - скорость: 75 байт - код, 45 байт - первая таблица, 30 байт -вторая, всего 150 байт (с циклами и без таблиц было бы байт 30, но раз в 10..100 медленнее). LTOA, конечно, раза в 2.5...3 длиннее и дольше, хотя есть у меня где-то хитрая уловка - LTOA из двух ITOA с домножением MSW на 0.65536, т.е. MSW=MSW*2048/3125, но на 8-битники еще не переложенная.

Вот, собственно, и спрашиваю - какие у кого есть уловки для ускорения xxx2BCD ?

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru