О чем я и толкую - для разных архитектур и задач оптимальное решение может быть разным Вот мой код для dsPIC:
<asm>
;------------------------------------------------------------------
; Converts an unsigned integer N in w0 to a 5-byte ASCII numerical string [w4]
; using a reciprocal multiplication and fractional conversion techniques
; 19 clocks including RETURN, 13 program words
itoa:
rev10k = 429497 ; ~= 2^32/10000
mov #rev10k >> 16,w1 ; Convert integer to fractional (equivalent to N/0.65536)
mul.uu w1,w0,w2 ; w3:w2 = partial product MSWs
mov #rev10k & 0xFFFF,w1
mul.uu w1,w0,w0 ; w1:w0 = partial product LSWs
add w1,w2,w0 ; w0 = fract(N%10000)
mov #'0',w2 ; w2 = ASCII bit mask, will also be used later
addc.b w3,w2,[w4++] ; w3 = N/10000, store an ASCII MS character
inc w0,w0 ; Correct a remainder to use 16-bit ops
do #3,1f ; Repeat the following code 4 times
mul.uu w0,#10,w0 ; w1 = next ASCII digit (0..9 range), w0 = fractional remainder
1: ior.b w1,w2,[w4++] ; Store a next ASCII character
return
;------------------------------------------------------------------
</asm>
Здесь я использовал совершенно другой алгоритм - сначала преобразовал integer во fractional, а потом уже полученный fractional преобразовывал в десятичный вид, последовательно умножая этот fractional на 10. На С этот код будет эффективно перевести достаточно затруднительно, да и эффективным он будет только для конкретной архитектуры - dsPIC.
Для AVR я тоже сделал пробный itoa по этому же принципу - оказалось весьма недурственно (код можно запросто свернуть раза в полтора, загнав mul10 в цикл):
<asm>
;--------------------------------------------------------------------
; Converts an unsigned integer r5:r4 to a 5-character ASCII string [x]
; 58 program words, 73 clocks + ret
itoa:
.equ rev10k = 429497 ; ~= 2^32/10000
clr r2
ldi r16,low(rev10k)
ldi r17,high(rev10k)
ldi r18,byte3(rev10k)
mul r4,r16
mov r6,r1
mul r4,r17
add r6,r0
adc r1,r2
mov r7,r1
mul r4,r18
add r7,r0
adc r1,r2
mov r8,r1 ; r8r7r6 ~= Xlsb*429497/256, 06872B max
mul r5,r16
add r6,r0
adc r7,r1
adc r8,r2
mul r5,r17
add r7,r0
adc r8,r1
mul r5,r18
add r8,r0 ; r8r7 ~= int2fract(X%10000)
ldi r17,'0'
adc r1,r17 ; r1 = ASCII(X/10000)
st x+,r1 ; Tens of thousands
;--------------------------------------------------------------------
; Converts fractional 16-bit value in r5:r4 (0..9999) range
; to a 4-character ASCII string [x]
; by sequential multiplication by 10
fractoa:
ldi r16,10 ; Constant for multiplication by 10
sec ; Correct int2fract result to fit in 16-bit word
adc r7,r2 ; by incrementing it
adc r8,r2 ;
mul r7,r16 ; Multiply a 16-bit value by 10
movw r2,r0 ;
mul r8,r16 ;
add r3,r0 ; r3r2 ~= int2fract(X%1000)
adc r1,r17 ; r1 = ASCII(X/1000)
st x+,r1 ; Thousands
mul r2,r16 ; Same as above for hundreds
movw r4,r0
mul r3,r16
add r5,r0
adc r1,r17
st x+,r1
mul r4,r16 ; Same as above for tens
movw r2,r0
mul r5,r16
add r3,r0
adc r1,r17
st x+,r1
mul r2,r16 ; Same as above for units
movw r4,r0
mul r3,r16
add r5,r0
adc r1,r17
st x+,r1
ret
;--------------------------------------------------------------------
</asm>
-
- Надо-ж...А я за этот вариант и браться не стал в своё время...А оно вононокак - mse homjak(10.02.2007 15:42, )
- Отож :) Хоть для AVR/x51 - выглядит некузяво, но для dsPIC-то код какой красивый, а? :)) - AVR(10.02.2007 16:27, )
- Вот. Я так и подумал - нех даже пытацца. И забил! ;О) - mse homjak(10.02.2007 16:41, )
- Отож :) Хоть для AVR/x51 - выглядит некузяво, но для dsPIC-то код какой красивый, а? :)) - AVR(10.02.2007 16:27, )
- Надо-ж...А я за этот вариант и браться не стал в своё время...А оно вононокак - mse homjak(10.02.2007 15:42, )