Autor Tema: Algoritmo de multiplicación en ensamblador  (Leído 8186 veces)

albanchez2k

  • Sinver
  • *
  • Mensajes: 2
  • SYS 0
    • Ver Perfil
Algoritmo de multiplicación en ensamblador
« en: Marzo 19, 2012, 11:12:06 »
Hola

Como ya sabréis, el 6502 solo puede realizar las operaciones de suma y resta con acarreo. Tanto la multiplicación como la división deben implementarse mediante algoritmo. Presento un algoritmo de multiplicación basado en el principio de desplazamiento aritmético. Esta escrito en el ensamblador kickass.

:BasicUpstart2(inicio)         // "trampolín" basic llamador del programa

.const M   = $10            //Multiplicando
.const m   = $11            //multiplicador
.const r1  = $12            //resultado 1
.const r2  = $13            //resultado 2
.const max = $ff            //valor maximo
.const min = $00            //valor minimo
.const ite = $08            //Iteraciones

.pc = $810 "Codigo"

// Codigo del programa
inicio:
         sei            //desactiva interrupciones
         lda V1         //inicializo Multiplicando
         sta M         //
         lda V2         //inicializo multiplicador
         sta m         //
         lda #min         //inicializo resultado
         sta r2         //
         ldx #ite         //inicializo x
         
bucle:
         lsr m            //desplazo m a la derecha
if:      bcc eif            //si acarreo = 0 salto eif
         clc
         adc M         //sumo M
eif:      ror             //roto acum a la derecha      
         ror r2         //roto r2 a la derecha
         dex            //decremento x
         bne bucle         //salto a bucle
fin:   
         sta r1         //muevo resul a r1
         cli            //activa interrupciones
         rts             // vuelve al BASIC
// Datos
V1:    .byte 0                     //Variable Multiplicador
V2:    .byte 0                //Variable multiplicando



V1 es la variable de entrada del multiplicador y V2 del multiplicando.
r1 y r2 son los registros de resultado. r1 para el byte alto y r2 para el byte bajo.

Se puede probar mediante:

poke2109,MMM:poke2110,mmm
sys2064
print peek(18):print peek(19) 

Teniendo en cuenta que los valores devuelto por los peek hay que convertirlos a hexadecimal. Por ejemplo:

MMM = 25
mmm = 13
25*13 = 325 –> Hex = 01 45
peek(18) = 1–> Hex = 01
peek(19) = 69 –> Hex = 45
« última modificación: Abril 04, 2012, 12:07:42 por albanchez2k »

Carlos

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 652
    • Ver Perfil
Re:Algoritmo de multiplicación en ensamblador
« Respuesta #1 en: Marzo 19, 2012, 12:13:56 »
Para un código no crítico hacer la multiplicación con un algoritmo puede valer pero para uno crítico (y a no ser que sea una multiplicación por potencia de 2) solo hay una solución: tablas.

PD: Por cierto, bienvenido  ;D

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13630
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Algoritmo de multiplicación en ensamblador
« Respuesta #2 en: Marzo 19, 2012, 19:38:05 »
Bienvenido albanchez2k! (vaya entrada al foro :P)
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

lobogris

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 453
  • Programador
    • Ver Perfil
    • http://back2theretro.blogspot.com
Re:Algoritmo de multiplicación en ensamblador
« Respuesta #3 en: Febrero 05, 2013, 21:10:43 »
acabo de sacar una rutina de multiplicación muy rápida ...
Código: [Seleccionar]
/*
  *************************************************************************************
                       RUTINA  DE  MULTIPLICACION RAPIDA * 320
 
  ENTRADAS:
  $fa     = numero multiplicador (1 byte, rango efectivo = 0 < 204)
 
  SALIDAS:
  $fb-$fc = resultado del multiplicador * 320 (precisión 16 bits)
 
  DETALLES:   
    Num. de ciclos          = 51 (+12 contando ciclos del JSR/RTS)
    Tamaño en memoria       = 29 bytes
    Max resultado teorico   = 255 * 320 = 81600 ($013EC0)
                            (no cabe en 16 bits, habria que adaptar resultado a 3 bytes)
    Max. resultado efectivo = 204 * 320 = 65280 ($FF00)
   
    Si se quiere optimizar para menor tamaño, se pueden incluir las rotaciones
    como una parte iterada dos veces por un bucle. Pero perdemos ciclos asi...

   FECHA CREACION: 05-03-13  ,   ULT. REV.: 05-03-13                           (LOBOGRIS)
  ***************************************************************************************
*/

fastMUL320:
            // Descomponiendo, resultado de n * 320 = (256 * n)  + (64 * n)
            // ahora vamos a calcular 64*numero
            // esto se consigue poniendo numero en la parte alta del resultado para obtener numero*256
            // y desplazaremos (todos los 16 bits) de resultado a la derecha 2 veces para
            // conseguir numero*64...
           
            lda numero
            clc                 // Primera rotacion lógica a la derecha (16 bits)
            lsr                 
            sta resultado+1     // Num. en parte alta resultado = multiplicar Num. * 256)
            lda resultado
            ror
            sta resultado       // Tras 1a rotación, resultado = 128 * numero
       
            clc                 // 2a rotacion a la derecha (16 bits)
            lda resultado+1
            lsr                 
            sta resultado+1
            lda resultado
            ror
            sta resultado       // aqui resultado = 64 * numero
           
            // Ahora haremos resultado = (numero * 256) + (numero * 64)
            lda numero          // Recupera numero. Al ponerlo parte alta = numero * 256
            adc resultado+1     // se añade a resultado*64 (parte alta es la única afectada)   
            sta resultado+1     // ¡Ahora resultado = 320 * numero!
            rts
« última modificación: Febrero 05, 2013, 21:12:31 por lobogris »

lobogris

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 453
  • Programador
    • Ver Perfil
    • http://back2theretro.blogspot.com
Re:Algoritmo de multiplicación en ensamblador
« Respuesta #4 en: Febrero 05, 2013, 21:20:06 »
Adjunto por aqui un paquetillo con el codigo fuente completo y su prg con el que la he estado verificando...

Por cierto, la rutina es un desafio simplemente, es mucho más rápido usar tablas, claro. ;)
« última modificación: Febrero 05, 2013, 21:24:02 por lobogris »

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13630
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Algoritmo de multiplicación en ensamblador
« Respuesta #5 en: Febrero 05, 2013, 22:33:53 »
Lobogris no descansa!
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com