ASSEMBLY - PICCOLA MODIFICA A PROGRAMMA

di il
4 risposte

ASSEMBLY - PICCOLA MODIFICA A PROGRAMMA

    

;------------------------------------------------------------------------------
  TITLE -  Programma N° 33
;------------------------------------------------------------------------------

;----------------------------------------------------------
; Prova Assembler esame di Calcolatori Elettronici A  -  26/01/2007
;----------------------------------------------------------
;NOME: prog33.asm
;AUTORE: Mattia Panciroli (157499)
;DESCRIZIONE: Programma N. 33
;
;
;	Il programma deve:
;	- accettare in ingresso un numero di quattro cifre
;	- stampare tutti i numeri (di 4 cifre) diversi tra loro che è possibile
;	  formare con le cifre del primo numero
;	- stampare i numeri in modo che compaiano in una sola schermata
;	- stampare i numeri in ordine crescente

;**********************************************************
; Definizioni costanti
;**********************************************************

;----------- 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

;--------- Gestione tastiera ----------
KEY_IO_SERVICE    EQU   16h   ; Interrupt gestione tastiera
R_KEY             EQU   00h   ; Legge un carattere

;----------- Interrupt DOS ------------
DOS               EQU   21h   ; Interrupt DOS
PRINT_STRING      EQU   09h   ; Stampa stringa


;--------- Costanti programma ---------
; Costanti realtive a tasti della tastiera e caratteri
TASTO_INVIO       EQU   0Dh
BS                EQU   08h
HT                EQU   09h
CR                EQU   0Dh
LF                EQU   0Ah

;**********************************************************
; Definizioni variabili
;**********************************************************

DSEG SEGMENT PARA PUBLIC 'DATA'

;-------- Stringhe da stampare --------
; Stringhe di output del programma
  PRESENTAZIONE_S   DB    HT,HT,'SEQUENZA ORDINATA DI NUMERI DECIMALI A 4 CIFRE',CR,LF,'$'
  IMMISSIONE        DB    CR,LF,'Inserire quattro cifre decimali: $'
  TERMINE           DB    CR,LF,CR,LF,'Ripetere? (s\n) $'

;-------- Variabili programma ---------
  V                 DB    4 DUP(0)   ; Vettore che memorizza le quattro cifre
  E					DW	  0          ; Numero corrente

DSEG ENDS



;**********************************************************
; Definizione stack
;**********************************************************

STACKM SEGMENT PARA STACK 'STACK'

  DB  64 DUP('        ')

STACKM ENDS



;**********************************************************
; Codice programma
;**********************************************************

  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  STAMPA_SEQUENZA   ; 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



;* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;----------------------------------------------------------
;|                       Procedure                        |
;----------------------------------------------------------


;----------------------------------------------------------
;------------- Procedura di inizializzazione --------------
;
; Registri utilizzati:  AX, DS
;----------------------------------------------------------

INIZIALIZZAZIONE    PROC NEAR

      MOV   AX,DSEG           ; Inizializzazione segmento dati
      MOV   DS,AX

      CALL  SETTA_MOD_VIDEO

    RET

INIZIALIZZAZIONE    ENDP


;----------------------------------------------------------
;--------------- Procedura di presentazione ---------------
;
; Registri utilizzati:  DX
;----------------------------------------------------------

PRESENTAZIONE   PROC NEAR

      MOV   DX,offset PRESENTAZIONE_S
      CALL  STAMPA_STRINGA

    RET

PRESENTAZIONE   ENDP


;----------------------------------------------------------
;-------------- Procedura per leggere i dati --------------
;
; Ritorna:              V inizializzato
; Registri utilizzati:  AL, DX
;----------------------------------------------------------

LEGGI_DATI    PROC NEAR

      MOV   DX,offset IMMISSIONE
      CALL  STAMPA_STRINGA

      CALL  LEGGI_CIFRA
      MOV   [V+0],AL
      CALL  LEGGI_CIFRA
      MOV   [V+1],AL
      CALL  LEGGI_CIFRA
      MOV   [V+2],AL         
      CALL  LEGGI_CIFRA
      MOV   [V+3],AL
	  RET

LEGGI_DATI    ENDP


;----------------------------------------------------------
;----------- Procedura per stampare la sequenza---------
;
; Parametri:            V,E
; Registri utilizzati:  AX,BX, CX, DX
;----------------------------------------------------------

STAMPA_SEQUENZA   PROC NEAR
;---------------------------------
      MOV   DX,0400h              ; Sposta il cursore in (4,0)
      CALL  SPOSTA_CURSORE
;---------------------------------

; Procedura di ordinamento del vettore V
      XOR   AX,AX
SU1:
      MOV   DI,AX
	  MOV   CL,V[DI]
	  
	  MOV   BX,AX
	  INC   BX
SU2:	  
      	  MOV DI,BX
		  CMP CL,V[DI]
		  JNG GIU
		  
		  MOV CH,V[DI]
		  MOV V[DI],CL
		  MOV DI,AX
		  MOV V[DI],CH
		  MOV CL,CH
		
GIU:		
 		  INC   BX
          CMP   BX,4
	      JNE   SU2

	  INC   AX
	  CMP   AX,3
	  JNE   SU1

	  
	  
	; Inizio algoritmo sequenza
    MOV [E],-1   ; Inizializzo numero corrente


      MOV CH,0
 A1:
         MOV CL,0
  A2:
            MOV DH,0
   A3:
               MOV DL,0
    A4:

                  ; Test di verifica che tutte le cifre siano tutte diverse
				  CMP CH,CL
				  JE NULLA
                  CMP CH,CL
				  JE NULLA
                  CMP CH,DH
				  JE NULLA
                  CMP CH,DL
				  JE NULLA
                  CMP CL,DH
				  JE NULLA
                  CMP CL,DL
				  JE NULLA
                  CMP DL,DH
				  JE NULLA

                  ; Test di verifica che il numero corrente sia maggiore del precedente
				  CALL CONV_DEC
                  CMP [E],AX
                  JGE NULLA
                  MOV [E],AX
          
		          ; Il numero formalmente corretto per la sequenza viene stampato
				  CALL STAMPA_NUMERO
 
     NULLA:
                  INC DL
                  CMP DL,4
                  JNE A4

               INC DH
               CMP DH,4
               JNE A3

            INC CL
            CMP CL,4
            JNE A2

         INC CH
         CMP CH,4
         JNE A1
	  
    RET

STAMPA_SEQUENZA   ENDP


;----------------------------------------------------------
;----------- Procedura per convertire gli elementi del vettore in numero---------
;
; Parametri:  V contiene le quattro cifre decimali
; Registri utilizzati:  AX,BX, CX, DX
; Ritorna:  AX numero convertito
;----------------------------------------------------------

CONV_DEC    PROC NEAR

		PUSH DX
		XOR AX,AX
        XOR BX,BX

		MOV BL,CH     ; Carico la prima cifra in AL
        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
		MOV BX,10     ; Moltiplico AX x10
		MUL BX

		POP DX
		PUSH DX
		
		MOV BL,DH     ; Carico la terza cifra in BL
        MOV DI,BX
		XOR BH,BH
        MOV BL,V[DI]
		ADD AX,BX     ; Sommo la terza cifra ad AX
		MOV BX,10     ; Moltiplico AX x10
		MUL BX

		POP DX
		PUSH DX

		MOV BL,DL     ; Carica la quarta cifra in BL
        MOV DI,BX
		XOR BH,BH
        MOV BL,V[DI]
		ADD AX,BX     ; Sommo la quarta cifra ad AX

		POP DX
    RET

CONV_DEC    ENDP



;* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;----------------------------------------------------------
;|       Procedure di basso livello di interfaccia        |
;----------------------------------------------------------


;----------------------------------------------------------
;--------- Procedura che setta la modalita' video ---------
;
; Registri utilizzati:  AX, DX
;----------------------------------------------------------

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 stampare un numero da 0 a 9999 ------
;
; Paramentri:           AX numero da stampare
; Registri utilizzati:  AX, BL, CX
;----------------------------------------------------------

STAMPA_NUMERO   PROC NEAR

      PUSH AX
	  PUSH BX
	  PUSH CX
	  PUSH DX

      XOR DX,DX
	  MOV BX,10               ; Divido il numero x10
	  DIV BX                  ; Il resto sono le unità
	  PUSH DX                 ; Salvo nello stack

      XOR DX,DX               ; Ripeto l'operazione
	  DIV BX
	  PUSH DX

      XOR DX,DX               ; Ripeto l'operazione
	  DIV BX
	  PUSH DX

      CALL  STAMPA_CIFRA      ; Stampa le migliaia
	  POP AX
      CALL  STAMPA_CIFRA      ; Stampa le centinaia
      POP AX
      CALL  STAMPA_CIFRA      ; Stampa le decine
      POP AX
	  CALL  STAMPA_CIFRA      ; Stampa le unità

      MOV   AL,' '
      CALL  STAMPA_CAR
	  
      POP DX
	  POP CX
	  POP BX
	  POP AX
	  
    RET

STAMPA_NUMERO   ENDP


;----------------------------------------------------------
;-------- Procedura per leggere una cifra da 0 a 9 --------
;
; Ritorna:              Zero_flag = 0  premuto invio
;                       Zero_flag = 1  letta cifra
;                       AL cifra letta
; Registri utilizzati:  AH
;----------------------------------------------------------

LEGGI_CIFRA   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_CAR
      MOV   AL,BL

      SUB   AL,'0'
      XOR   AH,AH             ; Setta lo Zero_flag

    RET

LEGGI_CIFRA   ENDP


;----------------------------------------------------------
;-- Procedura per stampare una cifra da 0 a 9 con blank ---
;
; Parametri:            BL = 0   blank
;                       BL <> 1  zero
;                       AL cifra
; Registri utilizzati:  
;----------------------------------------------------------

STAMPA_CIFRA   PROC NEAR

      PUSH AX
      PUSH BX
      PUSH CX
      PUSH DX

      ADD   AL,'0'            ; altrimenti stampo la cifra
      CALL  STAMPA_CAR

      POP DX
      POP CX
      POP BX
      POP AX

    RET

STAMPA_SPAZIO:
      MOV   AL,' '
      CALL  STAMPA_CAR

    RET

STAMPA_CIFRA   ENDP


;----------------------------------------------------------
;---------- Procedura per vedere se teriminare  -----------
;
; Ritorna:              Zero_flag = 0  ripeti
;                       Zero_flag = 1  esci
; Registri utilizzati:  AL, DX
;----------------------------------------------------------

TEST_FINALE   PROC NEAR

      MOV   DX,offset TERMINE    ; Stampa la richiesta
      CALL  STAMPA_STRINGA

      CALL  LETTURA_SN           ; Leggere risposta
      CMP   AL,'n'

    RET

TEST_FINALE   ENDP


;----------------------------------------------------------
;------------- Procedura per stampare stringa -------------
;
; Paramentri:           DS:DX indirizzo stringa
; Registri utilizzati:  AH, DX
;----------------------------------------------------------

STAMPA_STRINGA    PROC NEAR

      MOV   AH,PRINT_STRING
      INT   DOS

    RET

STAMPA_STRINGA    ENDP


;----------------------------------------------------------
;-- Procedura per leggere da tastiera i caratteri S o N ---
;
; Ritorna:              AL codice ascii del tasto letto
; Registri utilizzati:  AX
;----------------------------------------------------------

LETTURA_SN    PROC NEAR

NUOVA_LETTURA:
      CALL  LEGGI_TASTO_NE

      OR    AL,00100000b      ; Rende il carattere minuscolo
      CMP   AL,'n'            ; Se il tasto è 'n'
      JZ    FINE_LETTURA      ; termina la procedura
      CMP   AL,'s'            ; Se il tasto non è 's'
      JNZ   NUOVA_LETTURA     ; ripete la lettura

FINE_LETTURA:
    RET

LETTURA_SN    ENDP


;----------------------------------------------------------
;------- Procedura per leggere un tasto senza eco --------
;
; Ritorna:              AL codice ascii del tasto letto
; Registri utilizzati:  AX
;----------------------------------------------------------

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 -----------
;
; Ritorna:              AL carattere da stampare
; Registri utilizzati:  AX
;----------------------------------------------------------

STAMPA_CAR    PROC NEAR

      MOV	AH,W_CHR_TTY  		  ; Scrive il carattere
      INT	BIOS_VIDEO

		RET

STAMPA_CAR    ENDP


;----------------------------------------------------------
;----------- Procedura per spostare il cursore ------------
;
; Ritorna:              DH	riga
;                       DL	colonna
; Registri utilizzati:  AX, BH
;----------------------------------------------------------

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


4 Risposte

  • Re: ASSEMBLY - PICCOLA MODIFICA A PROGRAMMA

    IN QUESTO CODICE SI STAMPANO A VIDEO UN NUMERO DI 4 CIFRE , POI TUTTE LE COMBINAZIONI A 4 CIFRE CON LE CIFRE DEL NUMERO MESSO IN PARTENZA, E INFINE SI METTONO IN ORDINE CRESCENTE LE SEGUENTI COMBINAZIONI. COME POSSO MODIFICARE IL PROGRAMMA IN MODO CHE VENGANO STAMPATE LE COMBINAZIONI A DUE CIFRE E NON A 4??????
  • Re: ASSEMBLY - PICCOLA MODIFICA A PROGRAMMA

    Ciao
    sinceramente non ho capito molto bene la richiesta rispetto al codice che hai postato.
    comunque se vuoi stampare le combinazioni a 2 a due di un numero immesso basta che fai :
    mov dl,0ah ;vado a capo cosi si vedono meglio le varie combinazioni
    call stampa_carattere
    mov dl,0ah ; vado ad inizio riga affichè le cose siano ordinate.
    call stampa_carattere
    mov byte ptr varciclo,4 ;o numero massimo degli elementi del vettore
    ciclo_primario: cmp byte ptr varciclo,0 ; verifico se tutte le condizioni sono state stampate
    je fine_ciclo_primario ; se si termino il programma
    mov cx,4 ; numero massimo di caratteri o messo 4 perchè tu volevi stampare le combinazioni
                  ;4 numeri ma se lo voglio aumentare non c'è problema.
    mov bx,offset v ; punto con bx al vettore che devo stampare
    inc bx ; punto l'elemento che voglio stampare
    ciclo_secondario: mov dl,v[0] ; carico il primo elemento
    call stama_carattere ; stampo il primo elemento
    mov dl,[bx] ; stampo l'elemento che ho puntato
    call stampa_carattere
    mov dl," " ; un spazio per non creare confusione
    call stampa_carattere ; stampo
    inc bx ;punto il prossimo elemento che deve essere stampato
    loop ciclo_secondario ; procedo per tutto il vettore
    xor ax,ax ; mi serve per scambiare l'elemento fisso
    xor bx,bx ; hai me anche questo mi serve per scambiare l'elemento
    mov al,varciclo ;puntiamo l'elemento con ilò quale deve effettuarsi lo scambio 
    push ax ; conservo l'elemento 
    xchg byte ptr v[ax],al ; prendo l'ultimo elemento
    xchg al,v[0] ; scambio ultimo elemento con il primo
    mov bl,al conservo il primo elemento
    pop ax ;vado a riprendere la posizione dell'ultimo elemento
    xchg byte ptr v[ax],bl ; vado a mettere il primo elemento all'ultimo posizione
    dec byte ptr varciclo ; decrementiamo per il ciclo principale ultima posizione
    mov dl,0dh         ;vado a capo cosi si vedono meglio le varie combinazioni
    call stampa carattere
    mov dl,0ah         ; vado ad inizio riga affichè le cose siano ordinate.
    call stampa carattere
    jmp short ciclo_primario ;vado al ciclo principale affinchè possano essere stampate 
                                         ;anche le altre cifre
    fine_ciclo_primario: ;metto la fine del programma
    spero di esserti stato d'aiuto
  • Re: ASSEMBLY - PICCOLA MODIFICA A PROGRAMMA

    Ciao, vorrei chiedere qualcosa a smalldragon, mi puoi dire dove si inscerice sto pezzo di codice nel programma di ellosma??
    grazie mille in anticipo
  • Re: ASSEMBLY - PICCOLA MODIFICA A PROGRAMMA

    Il blocco calcola le combinazioni a 2 a 2 cosi deve essere inserito nella routine stampa sequeza
Devi accedere o registrarti per scrivere nel forum
4 risposte