Buon pomeriggio a tutti.
In un progetto assembler che devo svolgere mi viene richiesto di inserire un numero di 5 cifre e di creare tutte le combinazioni di numeri diversi disponibili. Il programma è funzionante, ma ha un piccolo problema...
Esempio, se inserisco 12345 ciò che deve uscire è:
12 13 14 15 21 23 24 25 31 ecc...
Ma considerando il numero 12321 ciò che il mio programma fa è:
11 12 12 13 11 12 13 21 21 22 23 21 21 22 23 31 31 32 32, ossia ripete certi numeri perchè nel numero che inserisco sono ripetuti più di una volta.
Quello che dovrei fare è far si che non stampi i doppioni. Qualcuno può aiutarmi?!

Lascio il codice del mio programma
codice:
;----------- Gestione video -----------
PAGINA            EQU   00h
;-------- Gestione bios video ---------
BIOS_VIDEO        EQU   10h   ;Interrupt gestione video
SET_VIDEO_MODE    EQU   00h   ;Impostazione modalita' video
MODO_TESTO        EQU   03h   ;Modaliita' 80 x 25 caratteri a colori
W_CHR_TTY         EQU   0Eh   ;Scrittura carattere
SET_CURSOR        EQU   02h   ;Posizione cursore
S_COLORE1         EQU   03H   ;Colore: azzurro su sfondo nero
S_COLORE2         EQU   05H   ;Colore: rosa su sfondo nero
KEY_IO_SERVICE    EQU   16h   ;Interrupt gestione tastiera
R_KEY             EQU   00h   ;Legge un carattere
DOS               EQU   21h   ;Interrupt DOS
PRINT_STRING      EQU   09h   ;Stampa stringa
TASTO_INVIO       EQU   0Dh
BS                EQU   08h
HT                EQU   09h
CR                EQU   0Dh
LF                EQU   0Ah
DSEG SEGMENT PARA PUBLIC 'DATA'
PRESENTAZIONE_S DB    HT,HT,'SEQUENZA ORDINATA DI NUMERI DECIMALI A 2 CIFRE',CR,LF,'$' 
IMMISSIONE      DB    CR,LF,'Inserire cinque cifre decimali: $' 
TERMINE         DB    CR,LF,CR,LF,'Ripetere? (s\n) $'
Testo01         DB    CR,LF,CR,LF,'DISPOSIZIONI SEMPLICI a due cifre dei 5 numeri acquisiti:',CR,LF,'$' 
Testo02         DB    CR,LF,CR,LF,'COMBINAZIONI SEMPLICI a due cifre dei 5 numeri acquisiti:',CR,LF,'$' 
Testo03         DB    CR,LF,CR,LF,'DISPOSIZIONI CON RIPETIZIONE a due cifre dei 5 numeri acquisiti:',CR,LF,'$' 

V                 DB    4 DUP(0)         ;Vettore che memorizza le quattro cifre
E		          DW	0                ;Numero corrente
TABLE             DB    20 DUP(0)

DSEG ENDS

STACKM SEGMENT PARA STACK 'STACK'
		DB  64 DUP('        ')
STACKM ENDS
ASSUME CS:CSEG, DS:DSEG, SS:STACKM

CSEG SEGMENT PARA PUBLIC 'CODE'

;|               Corpo pincipale programma               |;

MAIN	PROC FAR

	PUSH  DS        ;Istruzioni necessarie da lasciare in
	MOV   AX,00h     ;questa posizione
	PUSH  AX
	CALL  INIZIALIZZAZIONE
CICLO_PRINCIPALE:
	CALL  PRESENTAZIONE  ;Stampa etichetta programma
        CALL  LEGGI_DATI  ;Legge il numero in ingresso
        CALL  Ordina     
        MOV   DX,offset Testo01 
        CALL  STAMPA_STRINGA ;'DISPOSIZIONI SEMPLICI delle 5 cifre'
        CALL  STAMPA_New_01  ;Stampa la sequenza ordinata di numeri 
        CALL  TEST_FINALE   ;Ripetere? (s/n)
	    JZ    FINE
	    CALL  SETTA_MOD_VIDEO   ;Pulisce lo schermo
	    JMP   CICLO_PRINCIPALE
FINE:
	    CALL  SETTA_MOD_VIDEO  ;Ripristina il video e pulisce lo schermo
	    RET
MAIN	ENDP
;------------- Procedura di inizializzazione --------------;
; Registri utilizzati:  AX, DS                            

INIZIALIZZAZIONE    PROC NEAR

	MOV   AX,DSEG   ;Inizializzazione segmento dati
	MOV   DS,AX
	CALL  SETTA_MOD_VIDEO   ;Pulisce lo schermo
	RET
INIZIALIZZAZIONE    ENDP
;--------------- Procedura di presentazione ---------------;

PRESENTAZIONE   PROC NEAR
	MOV   DX,offset PRESENTAZIONE_S
	CALL  STAMPA_STRINGA
	RET
PRESENTAZIONE   ENDP
;-------------- Procedura per leggere i dati --------------;
LEGGI_DATI    PROC NEAR
	MOV   DX,offset IMMISSIONE
	CALL  STAMPA_STRINGA
	CALL  LEGGI_CIFRA_N      ;Inserisco la prima cifra
 	MOV   [V+0],AL     ;e la salvo nella prima locazione del vettore
	CALL  LEGGI_CIFRA_N    ;Inserisco la seconda cifra
	MOV   [V+1],AL    ;e la salvo nella seconda locazione del vettore
	CALL  LEGGI_CIFRA_N    ;Inserisco la terza cifra
	MOV   [V+2],AL    ;e la salvo nella terza locazione del vettore
	CALL  LEGGI_CIFRA_N   ;Inserisco la quarta cifra
	MOV   [V+3],AL       ;e la salvo nella quarta locazione del vettore
	CALL  LEGGI_CIFRA_N    ;Inserisco la quinta cifra
	MOV   [V+4],AL    ;e la salvo nella quinta locazione del vettore
	RET
LEGGI_DATI    ENDP
;--------- Procedura per ORDINARE la sequenza acquisita ------;

Ordina  PROC NEAR 

; Procedura di ordinamento del vettore V
	XOR   AX,AX  ;Azzero il registro         
SU1:
	MOV   DI,AX    ;Copia nel registro DI il contenuto del registro AX
	MOV   CL,V[DI]  ;Copia in CL l’elemento dell’array V di indice DI 
	MOV   BX,AX                  
	INC   BX     ;Incrementa BX
SU2:	  
	MOV DI,BX    ;Copia nel registro DI il contenuto del registro BX
	CMP CL,V[DI]  ;Copia in CL l’elemento dell’array V di indice DI
	JNG GIU  ;Salta, se non maggiore con segno, a GIU		  
	MOV CH,V[DI]   ;Copia in CH l’elemento dell’array V di indice DI
	MOV V[DI],CL    ;Copia nell'indice DI della'array V il contenuto di CL	
	MOV DI,AX    ;Copia nel registro DI il contenuto del registro AX
	MOV V[DI],CH   ;Copia nell'indice DI della'array V il contenuto di CH
	MOV CL,CH		
GIU:		
 	INC   BX     ;Incrementa BX
    CMP   BX,5    ;Confronto che BX sia uguale a 5
	JNE   SU2     ;Salta, se non uguale a 5, a SU2
	INC   AX    ;Incremento AX
	CMP   AX,4   ;Confronto che AX sia uguale a 4
	JNE   SU1   ;Salta, se non uguale a 4, a SU1
        RET
Ordina  ENDP  
;-----------------Procedura per stampare la sequenza---------------;

STAMPA_New_01   PROC NEAR 

	    MOV	    CX,4   ;Imposto che si ripeta 4 volte
	    MOV	    SI,0000H
x11:    MOV     DI,0000H
	    MOV   	AL,V[DI] 
	    CALL    STAMPA_COLORE2 ;Stampa il carattere in "rosa su sfondo nero"
	    CALL 	STAMPA_CAR ;Scrive il carattere 
	    INC	    SI
	    MOV   	AL,V[SI] 		
        CALL    STAMPA_COLORE2	
	    CALL 	STAMPA_CAR   ;Scrive il carattere
	    CALL 	STAMPA_SPAZIO
        LOOP    x11	
        MOV     CX,4   ;Di volta in volta punta
x12:    INC     DI   ;le rimanenti cifre del
        PUSH    CX   ;vettore ordinato
	    MOV	    CX,4 
        MOV     SI,-1
x13:    MOV     AL,V[DI]
        CALL    STAMPA_COLORE2    ;Stampa il carattere in "rosa su sfondo nero"
	    CALL 	STAMPA_CAR  ;Scrive il carattere 
        INC     SI
        CMP     SI,DI
        JNE     x14
        INC     SI
x14:    MOV     AL,V[SI]
        CALL    STAMPA_COLORE2 ;Stampa il carattere in "rosa su sfondo nero"
	    CALL 	STAMPA_CAR   ;Scrive il carattere
        CALL    STAMPA_SPAZIO
        LOOP    x13        
        POP     CX
        LOOP    x12
        RET
STAMPA_New_01   ENDP 
 
;-----Procedura per convertire gli elementi del vettore in numero-----;
CONV_DEC  PROC NEAR
	      PUSH DX
	      XOR AX,AX
          XOR BX,BX
	      MOV BL,CH  ;Carico la prima cifra in BL
          MOV DI,BX
          MOV AL,V[DI]
	      MOV BX,10  ;Moltiplico la prima cifra x10 
	      MUL BX
	      MOV BL,CL  ;Carico la seconda cifra in BL
          MOV DI,BX
	      XOR BH,BH
          MOV BL,V[DI]
	      ADD AX,BX  ;Sommo la seconda cifra alla prima moltiplicata x10
	      POP DX
	      RET
CONV_DEC    ENDP

;--------- Procedura che setta la modalita' video ----------;
SETTA_MOD_VIDEO   PROC NEAR
	MOV   AH,SET_VIDEO_MODE     ;Impostazione modalità video
	MOV   AL,MODO_TESTO         ;e pulizia lo schermo
	INT   BIOS_VIDEO
	MOV   DX,0000h              ;Sposta il cursore in (0,0)
	CALL  SPOSTA_CURSORE
	RET
SETTA_MOD_VIDEO   ENDP

;-----------Procedura per leggere una cifra da 0 a 9 ----------------;

LEGGI_CIFRA_N   PROC NEAR  

RILEGGI:
	CALL  LEGGI_TASTO_NE
	CMP   AL,'0'  ;Controlla sia un cifra se no rilegge
	JL    RILEGGI
	CMP   AL,'9'
	JG    RILEGGI
	MOV   BL,AL    ;Visualizza la cifra
	CALL  STAMPA_COLORE1  ;Stampa il carattere in "azzurro su sfondo nero"
	CALL  STAMPA_CAR
	MOV   AL,BL
	RET
LEGGI_CIFRA_N   ENDP

;Procedura per stampare una stringa;
STAMPA_STRINGA    PROC NEAR
	MOV   AH,PRINT_STRING
	INT   DOS
	RET
STAMPA_STRINGA    ENDP

;---------------------------------------------------------;
;------- Procedura per leggere un tasto senza eco --------;
LEGGI_TASTO_NE    PROC NEAR
	MOV   AH,R_KEY          ;Legge un carattere dal buffer
	INT   KEY_IO_SERVICE
	RET
LEGGI_TASTO_NE    ENDP

;----------------------------------------------------------;
;---------- Procedura per stampare un carattere -----------;
STAMPA_CAR    PROC NEAR
	MOV	AH,W_CHR_TTY  		  ;Scrive il carattere
	INT	BIOS_VIDEO
	RET
STAMPA_CAR    ENDP

;----------------------------------------------------------;
;----------- Procedura per spostare il cursore ------------;
SPOSTA_CURSORE    PROC NEAR
	MOV	BH,PAGINA
	MOV	AH,SET_CURSOR       ;Sposta il cursore
	INT	BIOS_VIDEO
	RET
SPOSTA_CURSORE    ENDP
CSEG ENDS

  END MAIN