Ordenar una tabla de menor a mayor en ensamblador

#1
¿Cómo podría hacer un programa que me ordene una tabla de menor a mayor en mplab?

Hice ésta pero creo que sólo me funciona para los valores que puse en la tabla, no sé cómo hacer si meto mas valores y en orden distinto en la tabla.

Gracias por su atención.

PHP:
; 4.4 DE UNA SERIE DE NUMEROS QUE INICIA EN LA DIRECCION (0X21) Y SU LONGITUD EN LA (0X20) ORDENAR DE MENOR A MAYOR

LIST P=16F877A ; SE DECLARA EL PROCESADOR A UTILIZAR
#INCLUDE <P16F877A.INC> ; SE DECLARA LA LIBRERIA DEL PIC16F877A
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ; SE HACE LA CONFIGURACION DE BITS

REG1 EQU 0X20 ; DECIMOS QUE REG1 ESTA EN LA DIRECCION 0X20
REG2 EQU 0X25 ; DECIMOS QUE REG2 ESTA EN LA DIRECCION 0X25
REG3 EQU 0X26 ; DECIMOS QUE REG3 ESTA EN LA DIRECCION 0X26
REG4 EQU 0X27 ; DECIMOS QUE REG4 ESTA EN LA DIRECCION 0X27
REG5 EQU 0X28 ; DECIMOS QUE REG5 ESTA EN LA DIRECCION 0X28

ORG 0X00 ; EL PROGRAMA INICIA EN LA DIRECCION 0X00

    CLRF REG1 ; SE LIMPIA EL REG1
    CLRF REG2 ; SE LIMPIA EL REG2
    CLRF REG3 ; SE LIMPIA EL REG3
    CLRF REG4 ; SE LIMPIA EL REG4
    CLRF REG5 ; SE LIMPIA EL REG5        

TABLA
    MOVLW 0x04 
    MOVWF 0X21
    MOVLW 0X01 
    MOVWF 0X22 
    MOVLW 0x02 
    MOVWF 0X23 
    MOVLW 0X03 
    MOVWF 0X24 


INICIO
    MOVLW 0X04 ; SE CARGA EN W UN 04 EN HEXADECIMAL (LONGITUD DE LA TABLA)  
    MOVWF REG1 ; SE MUEVE W AL REG1
    CLRW         ; SE LIMPIA W    
    MOVLW 0X21 ; SE CARGA EN W UN 21 EN HEXADECIMAL
    MOVWF FSR  ; SE MUEVE W A FSR, INDICANDOLE EN QUE DIRECCION DEBE POSICIONARSE
    CLRW       ; SE LIMPIA W
    

NUMERO1
    BTFSS INDF,0  ; SE PREGUNTA SI HAY UN UNO EN EL BIT 0 DE INDF
    GOTO NUMERO2  ; SALTA A NUMERO2
    MOVF INDF,W   ; SE MUEVE INDF A W
    MOVWF REG2    ; SE MUEVE W AL REG2
    INCF FSR,F    ; SE INCREMENTA FSR Y SE QUEDA EN FSR
    DECFSZ REG1,F ; SE DECREMENTA EL REG1 Y SE QUEDA EN EL REG1
    GOTO NUMERO2  ; SALTA A NUMERO2
    GOTO FIN      ; SALTA A FIN

NUMERO2
    BTFSS INDF,1  ; SE PREGUNTA SI HAY UN UNO EN EL BIT 1 DE INDF
    GOTO NUMERO3  ; SALTA A NUMERO3
    MOVF INDF,W   ; SE MUEVE INDF A W
    MOVWF REG3    ; SE MUEVE W AL REG3
    INCF FSR,F    ; SE INCREMENTA FSR Y SE QUEDA EN FSR
    DECFSZ REG1,F ; SE DECREMENTA EL REG1 Y SE QUEDA EN EL REG1
    GOTO NUMERO3  ; SALTA A NUMERO3
    GOTO FIN      ; SALTA A FIN

NUMERO3
    BTFSS INDF,0  ; SE PREGUNTA SI HAY UN UNO EN EL BIT 0 DE INDF
    GOTO NUMERO4  ; SALTA A NUMERO4
    BTFSS INDF,1  ; SE PREGUNTA SI HAY UN UNO EN EL BIT 1 DE INDF
    GOTO NUMERO4  ; SALTA A NUMERO4
    MOVF INDF,W   ; SE MUEVE INDF A W
    MOVWF REG4    ; SE MUEVE W AL REG4
    INCF FSR,F    ; SE INCREMENTA FSR Y SE QUEDA EN FSR
    DECFSZ REG1,F ; SE DECREMENTA EL REG1 Y SE QUEDA EN EL REG1
    GOTO NUMERO4  ; SALTA A NUMERO4
    GOTO FIN      ; SALTA A FIN

NUMERO4
    BTFSS INDF,2  ; SE PREGUNTA SI HAY UN UNO EN EL BIT 2 DE INDF
    GOTO NUMERO1  ; SALTA A NUMERO1
    MOVF INDF,W   ; SE MUEVE INDF A W
    MOVWF REG5    ; SE MUEVE W AL REG5
    INCF FSR,F    ; SE INCREMENTA FSR Y SE QUEDA EN FSR
    DECFSZ REG1,F ; SE DECREMENTA EL REG1 Y SE QUEDA EN EL REG1
    GOTO NUMERO1  ; SALTA A NUMERO1
    GOTO FIN      ; SALTA A FIN
FIN
    NOP           ; NO SE HACE NADA
     
END
 
Última edición por un moderador:

Dr. Zoidberg

Well-known-Papá Pitufo
#2
Mejor googleá sobre "bubble sort".
De todas formas, aun no entiendo como todavia existen profesores lo suficientemente estúpidos como para pedir ordenacion en assembler...
(A mi me tomaron lo mismo cuando rendí sistemas digitales 2, solo que mis numeros eran en complemento a dos y en doble precision. Zafé por que era ayudante de Computacion y sabia los algoritmos para ordenar números, por que el imbecil del docente nunca nos enseño nada diferente a operaciones en BCD)
 
Última edición:
#3
No lo he simulado, ni codificado ... pero te dara una ídea
ádemas ya que es un trabajo de tárea ... tienes tú que realizar el código
un video de diferentes métodos de ordenamiento lo encuentras en:



Código:
;  ORDENAR DE MENOR A MAYOR UNA SERIE DE NUMEROS
;   QUE INICIA EN LA DIRECCION (0X21)
;    Y SU LONGITUD EN LA (0X20)
;   Nota: No especifica donde ponemos los datos ordenados
;         Asi que suponemos que los dejamos empesando
;         en la dirección de inicio dada
;
;          Se utiliza metodo de la burbuja
;******************************************************************
;   
;     Se inicializa bandera a zero
; Inicio
;    Obten Número_actual  en W
;
;    Resta   Número_actual de  Número_actual + 1  (SUBWF file,W)
;        - Fué la resta menor a zero  ( Carry flag = 0)
;           No:  Terminamos ya?  (número datos < 0)
;                        Si: Hubo algun intercambio de registros (bandera =0)
;                                No: Salte ya terminamos
;                                Si:  continua
;                        No:  Decrementa número de datos
;                                incrementa dirección de número_actual
;                                y regresa al inicio
;
;            Si:   Bandera se ajusta - Incrementa bandera
;                  intercambian registros 
;                         ( temp   = número_actual + 1
;                           número_actual + 1 = número_actual
;                           número_actual = temp)
;                  incrementa dirección de número_actual
;                  Regresa a Inicio
;
; ****************************************************************
 
Última edición:
#4
Leyendo el libro "Programming and Customizing the PIC Microcontrollererd edition"
me encontre con esta macro que te puede servir para tu problema de Ordenacion

Código:
least macro reg1, reg2			; Compara dos valores y pon el
					;   de menor valor primero
		movf reg2, w
		subwf reg1, w			; Es reg 1 < Reg 2
		btfsc STATUS, C			; If no Carry, Swap the Values
		goto $+6 				;  No : Salte del macro
		movf reg1, w 			;  Si: Intercambia los valores de los
		xorwf reg2, w 			;       registros
		xorwf reg2
		xorwf reg2, w
		movwf reg1
endm

; y la forma de usar la macro seria:

		least regc, regd ; Move the Lowest Value to Front of
		least regb, regc ; beginning of List
		least regb, rega
		least regc, regd ; Move 2nd Lowest Value to 2nd from
		least regb, regc ; the Front
		least regc, regd ; Put the two highest in order
 
#5
PHP:
;
; Ordenación por selección directa de N elementos.
;   https://es.wikipedia.org/wiki/Ordenamiento_por_selecci%C3%B3n
;
; Joaquín Ferrero, 2015/10/03
;
; El sentido de la ordenación se hace por una instrucción skpc o skpnc.
; Se usa el algoritmo de selección directa (un poco más eficiente que el de la
; burbuja).

;
; Usamos dos variables extra: una temporal que guarda el máximo encontrado,
; para hacer el intercambio y otra para hacer de índice entre los valores.
;

; El código en C equivalente:
;
;    for (i = N-1; i > 1; i--) {    # recorremos todos los valores, excepto el último
;        tmp = vector[i];           # leemos el valor a comparar
;        for (k = i-1; k > 0; k--)  # recorremos desde la posición anterior, hasta el primero
;            if (vector[k] > tmp) { # si el valor es mayor que el que estamos comparando
;                tmp2 = tmp;        # los intercambiamos
;                tmp  = vector[k];
;                vector[k] = tmp2;
;            }
;        vector[i] = tmp;           # al final obtenemos el valor más grande, que guardamos en su posición
;    }


;*******************************************************************************
; Condiciones
                processor   16F877A
                radix       dec
                errorlevel  -302                ; Turn off banking message

;*******************************************************************************
; Bibliotecas

                include p16f877a.inc


;*******************************************************************************
; Programa

RES_VECT        code    0x0000                  ; processor reset vector
                goto    START                   ; go to beginning of program

                                                ; TODO ADD INTERRUPTS HERE IF USED

MAIN_PROG       code                            ; let linker place main program


; TODO: colocar un breakpoint aquí, y rellenar de N datos a partir de la dirección 'vector'
N               equ     10                      ; número de datos

START           call    seleccion               ; llamamos a la subrutina de ordenación

                goto    $                       ; fin de programa

; =============================================================================
; Rutina de ordenación de N datos
;
; El acceso a los datos se realiza por medio del registro FSR,
; que permite un acceso indexado. Ver
; DS31006A, 6.3.4 - Indirect Addressing, INDF and FSR Registers
;

SEL_SUB         code

seleccion:
                movlw   N-1                     ; for (i = N - 1;
                movwf   i
                addlw   vector
                movwf   FSR                     ; w => FSR (puntero al final de los datos)

loop1           movf    INDF,w                  ; tmp = vector[i]
                movwf   tmp

loop2           decf    FSR,f                   ; for (k = i-1; ...; k--)

                movf    tmp,w                   ; if (tmp - vector[k] < 0)
                subwf   INDF,w
                skpc                            ; cambiar a skpnc para cambiar el sentido
                goto    noswap

swap            movf    tmp,w                   ; tmp <=> vector[k]
                xorwf   INDF,f
                xorwf   INDF,w
                xorwf   INDF,f
                movwf   tmp

noswap          movlw   vector                  ; mientras k > 0;
                xorwf   FSR,w
                skpz                            ; sí
                goto    loop2                   ; no, continuar

                movlw   vector                  ; vector[i] = tmp
                addwf   i,w
                movwf   FSR
                movf    tmp,w
                movwf   INDF

                decf    FSR,f
                decfsz  i,f                     ; i--, ¿i == 0?
                goto    loop1                   ; no, continuar

                return                          ; si, terminar

; =============================================================================
; Espacio reservado para almacenar los valores
                udata_shr

vector          res    N
tmp             res    1                        ; almacena el máximo
i               res    1                        ; índice a los valores

;*******************************************************************************

                end
Esta solución no es óptima, ya que hace intercambios de elementos innecesarios (solo es necesario intercambiar el elemento máximo que encontramos con el elemento que estamos analizando), pero al menos, funciona.
 
Última edición:

Temas similares

Arriba