5 votos

32-bit entero sin signo de binario a BCD de 8 bits en ASM AVR para ATtiny. ¿Cómo hacer más eficiente?

Me escribió un programa en AVR ASM para la conversión de 32-bit unsigned números binarios a 8 digit decimales basado en el shift-add-3. (Sé que 32-bit es de más de 8 dígitos, pero sólo necesito 8.)

El 32-bit de entrada es en R16-R19 (bajo-alto).

El 8 digit de salida es en R20-R24 (baja-alta), 2 / número de bytes, uno en la parte inferior de picar, uno en el más alto nibble.

Mi problema: Se tarda ~1500 ciclos para calcular un 16-bit número y ~2000 ciclos para calcular un 32-bit.

¿Alguien puede sugerirme un más rápido, más profesional método para esto? Ejecución de un 2000 procedimiento del ciclo en un ATtiny en 32,768 Khz no es algo de lo que me siento cómodo con el.

El uso de la memoria del mapa:

Memory map for BinaryToBCD

Definiciones:

.def    a0  =   r16
.def    a1  =   r17
.def    a2  =   r18
.def    a3  =   r19

.def    b0  =   r20
.def    b1  =   r21
.def    b2  =   r22
.def    b3  =   r23

.def    i   =   r24
.def    j   =   r25

El código:

BinaryToBCD:
    clr     b0
    clr     b1
    clr     b2
    clr     b3
    ldi     i,  32
    sts     0x0068, i       ;(SRAM s8)

BinaryToBCD_1:
    clc
    rol     a0
    rol     a1
    rol     a2
    rol     a3
    rol     b0
    rol     b1
    rol     b2
    rol     b3

    lds     i, 0x0068       ;(SRAM s8)
    dec     i
    sts     0x0068, i       ;(SRAM s8)
    brne    BinaryToBCD_2
    ret

BinaryToBCD_2:
    cpi     b0,     0
    breq    BinaryToBCD_3
    mov     i,      b0
    rcall   Add3ToNibbles
    mov     b0,     i

BinaryToBCD_3:
    cpi     b1,     0
    breq    BinaryToBCD_4
    mov     i,      b1
    rcall   Add3ToNibbles
    mov     b1,     i

BinaryToBCD_4:
    cpi     b2,     0
    breq    BinaryToBCD_5
    mov     i,      b2
    rcall   Add3ToNibbles
    mov     b2,     i

BinaryToBCD_5:
    cpi     b3,     0
    breq    BinaryToBCD_1
    mov     i,      b3
    rcall   Add3ToNibbles
    mov     b3,     i
    rjmp    BinaryToBCD_1


Add3ToNibbles:
    mov     j,      i
    andi    j,      0b00001111
    cpi     j,      5
    in      j,      SREG
    sbrs    j,      0
    subi    i,      -3

    mov     j,      i
    swap    j
    andi    j,      0b00001111
    cpi     j,      5
    in      j,      SREG
    sbrs    j,      0
    subi    i,      -48
    ret

1voto

asndre Puntos 797

Esto se basa en el enfoque de venny (venny llamado triangulación), expresado en un "pseudo-C":

uint32 x; // input variable to convert

w = { 2, 1, 4, 7, 4, 8, 3, 6, 4, 8 }; // 2^31
r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // initial result = 0

for (i = 31; i >= 0; i --)
{
   if ( 2^i  AND x )  // is x's bit i up?
      add(r, w);      // if yes, 1 ASCII ADD and 9 ASCII ADD w/CARRY MAX
   divide(w, 2)       // 10 SHIFT RIGHT MAX
}

Añadir y dividir no es necesaria explicación, OMI.

0voto

jns Puntos 449

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X