Risultato errato[Risolto]

di il
5 risposte

Risultato errato[Risolto]

Salve a tutti!
Ho creato un piccolo programma che dovrebbe calcolare l'area di un triangolo qualsiasi dati in input base e altezza.
Ma c'è un problema: il risultato ottenuto alla fine è errato anche se secondo me i passaggi matematici per il calcolo dell'area del triangolo tradotti in assembly8086 sono corretti.

DATA SEGMENT PUBLIC
	
	INTRO DB "CALCOLATORE AREA TRIANGOLO!",10,13,'$'
	DOM1 DB "Digita il valore della base del triangolo: ",'$'
	DOM2 DB "Digita il valore della alterzza del triangolo: ",'$'
	RIS DB "Area del triangolo: ",'$'
	CHIUSURA DB "Fine del programma",10,13,'$'
	ACAPO DB 10,13,'$'
	BASE DB ?
	ALTEZZA DB ?
	NUM DB ?
	QUO DB ?
	RESTO DB ?
	DIECI DB 10 
	CONTA DB 0 
	DUE DB 2 
	DECIMALE DB ? 
	
DATA ENDS ;FINE DEL SEGMENTO DEI DATI

CODE SEGMENT

	ASSUME CS:CODE,DS:DATA
	
INIZIO:

	;CARICAMENTO DEI DATI
	MOV AX,DATA
	MOV DS,AX 

	MOV AX,03H ;RICHIESTA PULIZIA DELLO SCHERMO
	INT 10H ;INTERRUPT CHE PERMETTE LA PULIZIA DELLO SCHERMO
	
	STAMPA MACRO FRASE
		MOV AH,09H ;RICHIESTA STAMPA DELLA STRINGA
		LEA DX,FRASE ;CARICAMENTO DEI DATI
		INT 21H ;INTERRUPT CHE PERMETTE LA STAMPA DI UNA FRASE
	ENDM ;FINE DELLA MACRO PER LA STAMPA DELLE STRINGHE
	

	STAMPA INTRO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
	
	STAMPA DOM1 ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
	CALL INPUT ;RICHIAMO LA PROCEDURA PER L'INPUT DEL NUMERO 
	MOV BASE,BL 
	
	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
	
	STAMPA DOM2 ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
	CALL INPUT ;RICHIAMO LA PROCEDURA PER L'INPUT DEL NUMERO 
	MOV ALTEZZA,BL  
	
	CALL CALCOLO_AREA ;RICHIAMO LA PROCEDURA PER IL CALCOLO DELL'AREA DEL TRIANGOLO

	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
	STAMPA RIS ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
	CALL STAMPARIS ;RICHIAMO LA PROCEDURA PER ESEGUIRE LA STAMPA DEL RISULTATO
	
	MOV CH,00H
	MOV CL,QUO
	CALL STAMPARIS
	
	CMP RESTO,00H
	JNG FINEPROGRAMMA
	
	MOV AH,02H
	MOV DL,'.'
	INT 21H 
	
	MOV CH,00H
	MOV CL,DECIMALE
	CALL STAMPARIS
	
FINEPROGRAMMA:
	STAMPA ACAPO
	STAMPA CHIUSURA 
	
;RESTITUISCO IL CONTROLLO AL DOS
MOV AH,4CH
INT 21H

;PROCEDURE

INPUT PROC NEAR 

	MOV BX,0 ;AZZERO IL REGISTRO BX 
	MOV CONTA,0 
	
CICLO:
	MOV AH,01H ;RICHIESTA INPUT DI UN CARATTERE
	INT 21H ;INTERRUPT CHE PERMETTE INPUT DI UN CARATTERE
	
	CMP AL,0DH ;COMPARE FRA AL E IL VALORE DELLA TABELLA ASCII DEL TASTO INVIO 
	JE FINE ;SE IL TASTO PREMUTO è INVIO è FINITO L'INPUT
	
	ADD CONTA,1 
	CMP CONTA,2 
	JE FINE 
	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX
	PUSH AX ;METTO AX NELLO STACK
	MOV AX,BX 
	MUL DIECI ;MOLTIPLICO AX PER 10 
	MOV BX,AX 
	POP AX 
	SUB AL,30H 
	MOV AH,0
	ADD BX,AX 
	JMP CICLO ;FINE DEL CICLO 
	
FINE:
	RET ;RESTITUISCO IL CONTROLLO AL MAIN 
ENDP ;FINE DELLA PROCEDURA


CALCOLO_AREA PROC NEAR

	;AREA DEL TRIANGOLO = (BASE * ALTEZZA) / 2 
	
	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX 
	MOV AL,BASE ;METTO IN AL LA BASE
	MUL ALTEZZA ;MOLTIPLICO AX PER L'ALTEZZA 
	DIV DUE ;DIVIDO IL REGISTRO AX PER 2 --> QUOZIENTE IN AL E IL RESTO IN AH 
	MOV QUO,AL ;SALVO IL QUOZIENTE NELLA RISPETTIVA VARIABILE
	
	CMP AH,00H ;COMPARE FRA IL RESTO E AH 
	JE FINE1;SE IL RESTO è UGUALE A ZERO(NON ESISTE) SALTO ALLA FINE DELLA PROCEDURA
	MOV RESTO,AH ;SALVO IL RESTO NELLA RISPETTIVA VARIABILE
		
	CMP AH,9 ;COMPARE FRA IL RESTO E 9 
	JG CALCOLODECIM ;SE IL RESTO è PIù GRANDE DI 9 SALTA A "CALCOLODECIM"
	
	MOV AL,RESTO ;METTO IN AL IL RESTO
	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX 
	MUL DIECI ;MOLTIPLICO PER 10 IL REGISTRO AX
	MOV RESTO,AL ;SALVO IL RISULTATO NELLA VARIABILE RESTO
	
CALCOLODECIM:
	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX
	MOV AL,RESTO ;METTO IN AL IL RESTO
	DIV DUE ;DIVIDO IL REGISTRO AX PER 2 --> QUOZIENTE IN AL E IL RESTO IN AH 
	MOV DECIMALE,AL ;SALVO LA PARTE DECIMALE 
		
FINE1:	
	RET ;RESTITUISCO IL CONTROLLO AL DOS 

ENDP ;FINE DELLA PROCEDURA PER IL CALCOLODELL'AREA DEL TRIANGOLO

STAMPARIS PROC NEAR

	;AZZERAMENTO DEI DUE REGISTRI
	XOR AX,AX
	MOV CONTA,0 
	MOV AX,CX 
	MOV BL,DIECI
	
CICLODIV: ;inizio del ciclo	

	CMP AX,9 ;confronto il registro AX con 9 
	JG DIVISIONE ;se il numero è maggiore di 9 significa che è almeno a due cifre quindi bisogna dividere per 10 
	JLE NODIVISIONE ;se il numero è minore o uguale a nove si rappresenta di sicuro in un byte e salto il ciclo

	DIVISIONE: 
		MOV DH,00H
		MOV DL,00H
		;nel registro AX c'è il numero che devo dividere
		MOV BH,00H
		DIV BX ;divido per 10 che è contenuto in BX --> AX QUOZIENTE E DX RESTO!!!
		PUSH DX ;metto nello stack il resto della divisione che è contenuto in DX 
		;non tocco il registro ax in quanto contiene già il probabile successivo numero che deve dividere
		ADD CONTA,1 ;incremento la variabile contatore 
		JMP CICLODIV ;salto incondizionato a "CICLODIV" così da ripetere il ciclo
		
	NODIVISIONE:
		
		MOV NUM,AL 
		
		CMP CONTA,0 
		JZ STAMPA1 
		JNZ STAMPA2
		
		STAMPA1:
			MOV AH,02H ;richiesta per la stampa di un singolo carattere
			MOV DL,NUM ;sposto in DL il carattere 
			ADD DL,30H ;conversione 
			INT 21H ;interrupt che permette di stampa il carattere
			JMP EXIT ;salto incodizionato alla fine del programma
			
		STAMPA2:
			
			MOV AH,02H  ;richiesta per la stampa di un singolo carattere
			MOV DL,NUM ;sposto in DL il carattere 
			ADD DL,30H ;conversione 
			INT 21H ;interrupt che permette di stampa il carattere
			
			XOR AX,AX ;azzero il registro AX per sicurezza
			XOR BX,BX ;azzero il registro BX per sicurezza
			
		CICLOSTAMPA: ;ciclo per la stampa di un numero a più cifre
			POP BX ;tiro fuori il numero dallo stack in DX 
			MOV AH,02H ;richiesta per la stampa di un singolo carattere
			MOV DL,BL
			ADD DL,30H 
			INT 21H 
			SUB CONTA,1 ;decremento conta di 1 
			CMP CONTA,0
			JZ EXIT ;se la variabile conta è uguale a zero allora ha finito i numeri e quindi esco dal ciclo
			JNZ CICLOSTAMPA ;se la variabile non è zero allora ricomincio il ciclo per la stampa 
		
EXIT:
	RET 
ENDP ;FINE DELLA PROCEDURA PER LA STAMPA DEL RISULTATO 

CODE ENDS ;FINE DEL SEGMENTO DEL CODICE
END INIZIO ;CHIUSURA ETICHETTA CHE INDICA L'INIZIO DEL PROGRAMMA
Se qualcuno mi potrebbe aiutare a trovare l'errore lo ringrazio in anticipo

5 Risposte

  • Re: Risultato errato[Risolto]

    Ho trovato un errore che mi ha già aiutato a risolvere in parte il risultato, tuttavia si verifica una cosa strana

    ad esempio se in input digito
    base 12
    altezza 2
    il risultato è 1 come se eseguisse il prodotto solo fra 1 e 2 senza considerare il 12 come un numero unico.

    Ecco il sorgente
    DATA SEGMENT PUBLIC
    	
    	INTRO DB "CALCOLATORE AREA TRIANGOLO!",10,13,'$'
    	DOM1 DB "Digita il valore della base del triangolo: ",'$'
    	DOM2 DB "Digita il valore della alterzza del triangolo: ",'$'
    	RIS DB "Area del triangolo: ",'$'
    	CHIUSURA DB "Fine del programma",10,13,'$'
    	ACAPO DB 10,13,'$'
    	BASE DB ?
    	ALTEZZA DB ?
    	NUM DB ?
    	QUO DW ?
    	RESTO DW ?
    	DIECI DW 10 
    	CONTA DB 0 
    	DUE DW 2 
    	DECIMALE DW ? 
    	
    DATA ENDS ;FINE DEL SEGMENTO DEI DATI
    
    CODE SEGMENT
    
    	ASSUME CS:CODE,DS:DATA
    	
    INIZIO:
    
    	;CARICAMENTO DEI DATI
    	MOV AX,DATA
    	MOV DS,AX 
    
    	MOV AX,03H ;RICHIESTA PULIZIA DELLO SCHERMO
    	INT 10H ;INTERRUPT CHE PERMETTE LA PULIZIA DELLO SCHERMO
    	
    	STAMPA MACRO FRASE
    		MOV AH,09H ;RICHIESTA STAMPA DELLA STRINGA
    		LEA DX,FRASE ;CARICAMENTO DEI DATI
    		INT 21H ;INTERRUPT CHE PERMETTE LA STAMPA DI UNA FRASE
    	ENDM ;FINE DELLA MACRO PER LA STAMPA DELLE STRINGHE
    	
    
    	STAMPA INTRO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	
    	STAMPA DOM1 ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	CALL INPUT ;RICHIAMO LA PROCEDURA PER L'INPUT DEL NUMERO 
    	MOV BASE,BL ;SALVO IL NUMERO NELLA RELATIVA VARIABILE
    	
    	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	
    	STAMPA DOM2 ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	CALL INPUT ;RICHIAMO LA PROCEDURA PER L'INPUT DEL NUMERO 
    	MOV ALTEZZA,BL ;SALVO IL NUMERO NELLA RELATIVA VARIABILE
    	
    	CALL CALCOLO_AREA ;RICHIAMO LA PROCEDURA PER IL CALCOLO DELL'AREA DEL TRIANGOLO
    
    	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	STAMPA RIS ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	
    	XOR AX,AX 
    	MOV AX,QUO 
    	CALL STAMPARIS ;RICHIAMO LA PROCEDURA PER LA STAMPA DEL RISULTATO
    	
    	CMP RESTO,00H
    	JNG FINEPROGRAMMA
    	
    	MOV AH,02H
    	MOV DL,'.'
    	INT 21H 
    	
    	XOR AX,AX 
    	MOV AX,DECIMALE
    	CALL STAMPARIS
    	
    FINEPROGRAMMA:
    	STAMPA ACAPO
    	STAMPA CHIUSURA 
    	
    ;RESTITUISCO IL CONTROLLO AL DOS
    MOV AH,4CH
    INT 21H
    
    
    ;PROCEDURE
    INPUT PROC NEAR 
    
    	MOV BX,0 ;AZZERO IL REGISTRO BX 
    	MOV CONTA,0 
    	
    CICLO:
    	MOV AH,01H ;RICHIESTA INPUT DI UN CARATTERE
    	INT 21H ;INTERRUPT CHE PERMETTE INPUT DI UN CARATTERE
    	CMP AL,0DH ;COMPARE FRA AL E IL VALORE DELLA TABELLA ASCII DEL TASTO INVIO 
    	JE FINE ;SE IL TASTO PREMUTO è INVIO è FINITO L'INPUT
    	ADD CONTA,1 
    	CMP CONTA,2 
    	JE FINE 
    	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX
    	PUSH AX ;METTO AX NELLO STACK
    	MOV AX,BX 
    	MUL DIECI ;MOLTIPLICO AX PER 10 
    	MOV BX,AX  ;SPOSTO AX IN BX
    	POP AX ;ESTRAGGO DALLO STACK L'ULTIMO NUMERO INSERITO E LO METTO IN AX 
    	SUB AL,30H ;CONVERSIONE DEL CARATTERE DIGITATO IN NUMERO
    	MOV AH,0 ;AZZERO LA PARTE ALTA DI AX
    	ADD BX,AX ;SOMMA DEI DUE REGISTRI 
    	JMP CICLO ;FINE DEL CICLO 
    FINE:
    	RET ;RESTITUISCO IL CONTROLLO AL MAIN 
    ENDP ;FINE DELLA PROCEDURA
    
    
    CALCOLO_AREA PROC NEAR
    
    	XOR DX,DX ;AZZERO IL REGISTRO DX 
    
    	;AREA DEL TRIANGOLO = (BASE * ALTEZZA) / 2 
    	
    	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX 
    	MOV AL,BASE ;METTO IN AL LA BASE
    	MUL ALTEZZA ;MOLTIPLICO AX PER L'ALTEZZA 
    	DIV DUE ;DIVIDO IL REGISTRO AX PER 2 --> QUOZIENTE IN AL E IL RESTO IN AH 
    	MOV QUO,AX ;SALVO IL QUOZIENTE NELLA RISPETTIVA VARIABILE
    	
    	CMP DX,00H ;COMPARE FRA IL RESTO E AH 
    	JE FINE1;SE IL RESTO è UGUALE A ZERO(NON ESISTE) SALTO ALLA FINE DELLA PROCEDURA
    	MOV RESTO,DX  ;SALVO IL RESTO NELLA RISPETTIVA VARIABILE
    		
    	CMP DX,9 ;COMPARE FRA IL RESTO E 9 
    	JG CALCOLODECIM ;SE IL RESTO è PIù GRANDE DI 9 SALTA A "CALCOLODECIM"
    	
    	XOR AX,AX ;AZZERO IL REGISTRO AX 
    	MOV AX,RESTO ;METTO IN AL IL RESTO
    	MUL DIECI ;MOLTIPLICO PER 10 IL REGISTRO AX
    	MOV RESTO,AX ;SALVO IL RISULTATO NELLA VARIABILE RESTO
    	
    CALCOLODECIM:
    	XOR AX,AX ;AZZERO IL REGISTRO AX 
    	MOV AX,RESTO ;METTO IN AL IL RESTO
    	DIV DUE ;DIVIDO IL REGISTRO AX PER 2 --> QUOZIENTE IN AL E IL RESTO IN AH 
    	MOV DECIMALE,AX ;SALVO LA PARTE DECIMALE 
    		
    FINE1:	
    	RET ;RESTITUISCO IL CONTROLLO AL DOS 
    
    ENDP ;FINE DELLA PROCEDURA PER IL CALCOLODELL'AREA DEL TRIANGOLO
    
    STAMPARIS PROC NEAR
    	
    	XOR BX,BX ;AZZERO BX 
    	MOV CONTA,0  ;AZZERO LA VARIABILE CONTA 
    	MOV BX,DIECI ;METTO IN BX IL VALORE DELLA VARIABILE
    	
    CICLODIV: ;inizio del ciclo	
    
    	CMP AX,9 ;confronto il registro AX con 9 
    	JG DIVISIONE ;se il numero è maggiore di 9 significa che è almeno a due cifre quindi bisogna dividere per 10 
    	JLE NODIVISIONE ;se il numero è minore o uguale a nove si rappresenta di sicuro in un byte e salto il ciclo
    
    	DIVISIONE: 
    		MOV DH,00H
    		MOV DL,00H
    		;nel registro AX c'è il numero che devo dividere
    		DIV BX ;divido per 10 che è contenuto in BX --> AX QUOZIENTE E DX RESTO!!!
    		PUSH DX ;metto nello stack il resto della divisione che è contenuto in DX 
    		;non tocco il registro ax in quanto contiene già il probabile successivo numero che deve dividere
    		ADD CONTA,1 ;incremento la variabile contatore 
    		JMP CICLODIV ;salto incondizionato a "CICLODIV" così da ripetere il ciclo
    		
    	NODIVISIONE:
    		
    		MOV NUM,AL 
    		
    		CMP CONTA,0 
    		JZ STAMPA1 
    		JNZ STAMPA2
    		
    		STAMPA1:
    			MOV AH,02H ;richiesta per la stampa di un singolo carattere
    			MOV DL,NUM ;sposto in DL il carattere 
    			ADD DL,30H ;conversione 
    			INT 21H ;interrupt che permette di stampa il carattere
    			JMP EXIT ;salto incodizionato alla fine del programma
    			
    		STAMPA2:
    			
    			MOV AH,02H  ;richiesta per la stampa di un singolo carattere
    			MOV DL,NUM ;sposto in DL il carattere 
    			ADD DL,30H ;conversione 
    			INT 21H ;interrupt che permette di stampa il carattere
    			
    			XOR AX,AX ;azzero il registro AX per sicurezza
    			XOR BX,BX ;azzero il registro BX per sicurezza
    			
    		CICLOSTAMPA: ;ciclo per la stampa di un numero a più cifre
    			POP BX ;tiro fuori il numero dallo stack in DX 
    			MOV AH,02H ;richiesta per la stampa di un singolo carattere
    			MOV DL,BL
    			ADD DL,30H 
    			INT 21H 
    			SUB CONTA,1 ;decremento conta di 1 
    			CMP CONTA,0
    			JZ EXIT ;se la variabile conta è uguale a zero allora ha finito i numeri e quindi esco dal ciclo
    			JNZ CICLOSTAMPA ;se la variabile non è zero allora ricomincio il ciclo per la stampa 
    		
    EXIT:
    	RET 
    ENDP ;FINE DELLA PROCEDURA PER LA STAMPA DEL RISULTATO 
    
    CODE ENDS ;FINE DEL SEGMENTO DEL CODICE
    END INIZIO ;CHIUSURA ETICHETTA CHE INDICA L'INIZIO DEL PROGRAMMA
  • Re: Risultato errato[Risolto]

    Queste linee

    ADD CONTA,1
    CMP CONTA,2
    JE FINE

    non sono nel posto giusto ... pensaci ...
  • Re: Risultato errato[Risolto]

    Grazie per avermelo fatto notare e ho capito l'errore!

    Ecco il sergente del programma finale
    DATA SEGMENT PUBLIC
    	
    	INTRO DB "CALCOLATORE AREA TRIANGOLO!",10,13,'$'
    	DOM1 DB "Digita il valore della base del triangolo: ",'$'
    	DOM2 DB "Digita il valore della alterzza del triangolo: ",'$'
    	RIS DB "Area del triangolo: ",'$'
    	CHIUSURA DB "Fine del programma",10,13,'$'
    	ACAPO DB 10,13,'$'
    	BASE DB ?
    	ALTEZZA DB ?
    	NUM DB ?
    	QUO DW ?
    	RESTO DW ?
    	DIECI DW 10 
    	CONTA DB 0 
    	DUE DW 2 
    	DECIMALE DW ? 
    	
    DATA ENDS ;FINE DEL SEGMENTO DEI DATI
    
    CODE SEGMENT
    
    	ASSUME CS:CODE,DS:DATA
    	
    INIZIO:
    
    	;CARICAMENTO DEI DATI
    	MOV AX,DATA
    	MOV DS,AX 
    
    	MOV AX,03H ;RICHIESTA PULIZIA DELLO SCHERMO
    	INT 10H ;INTERRUPT CHE PERMETTE LA PULIZIA DELLO SCHERMO
    	
    	STAMPA MACRO FRASE
    		MOV AH,09H ;RICHIESTA STAMPA DELLA STRINGA
    		LEA DX,FRASE ;CARICAMENTO DEI DATI
    		INT 21H ;INTERRUPT CHE PERMETTE LA STAMPA DI UNA FRASE
    	ENDM ;FINE DELLA MACRO PER LA STAMPA DELLE STRINGHE
    	
    
    	STAMPA INTRO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	
    	STAMPA DOM1 ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	CALL INPUT ;RICHIAMO LA PROCEDURA PER L'INPUT DEL NUMERO 
    	MOV BASE,BL ;SALVO IL NUMERO NELLA RELATIVA VARIABILE
    	
    	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	
    	STAMPA DOM2 ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	CALL INPUT ;RICHIAMO LA PROCEDURA PER L'INPUT DEL NUMERO 
    	MOV ALTEZZA,BL ;SALVO IL NUMERO NELLA RELATIVA VARIABILE
    	
    	CALL CALCOLO_AREA ;RICHIAMO LA PROCEDURA PER IL CALCOLO DELL'AREA DEL TRIANGOLO
    
    	STAMPA ACAPO ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	STAMPA RIS ;RICHIAMO LA MACRO PER STAMPARE LA FRASE
    	
    	XOR AX,AX 
    	MOV AX,QUO 
    	CALL STAMPARIS ;RICHIAMO LA PROCEDURA PER LA STAMPA DEL RISULTATO
    	
    	CMP RESTO,00H
    	JNG FINEPROGRAMMA
    	
    	MOV AH,02H
    	MOV DL,'.'
    	INT 21H 
    	
    	XOR AX,AX 
    	MOV AX,DECIMALE
    	CALL STAMPARIS
    	
    FINEPROGRAMMA:
    	STAMPA ACAPO
    	STAMPA CHIUSURA 
    	
    ;RESTITUISCO IL CONTROLLO AL DOS
    MOV AH,4CH
    INT 21H
    
    
    ;PROCEDURE
    INPUT PROC NEAR 
    
    	MOV BX,0 ;AZZERO IL REGISTRO BX 
    	MOV CONTA,0 
    	
    CICLO:
    	MOV AH,01H ;RICHIESTA INPUT DI UN CARATTERE
    	INT 21H ;INTERRUPT CHE PERMETTE INPUT DI UN CARATTERE
    	CMP AL,0DH ;COMPARE FRA AL E IL VALORE DELLA TABELLA ASCII DEL TASTO INVIO 
    	JE FINE ;SE IL TASTO PREMUTO è INVIO è FINITO L'INPUT
    	ADD CONTA,1 
    	
    	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX
    	PUSH AX ;METTO AX NELLO STACK
    	MOV AX,BX 
    	MUL DIECI ;MOLTIPLICO AX PER 10 
    	MOV BX,AX  ;SPOSTO AX IN BX
    	POP AX ;ESTRAGGO DALLO STACK L'ULTIMO NUMERO INSERITO E LO METTO IN AX 
    	SUB AL,30H ;CONVERSIONE DEL CARATTERE DIGITATO IN NUMERO
    	MOV AH,0 ;AZZERO LA PARTE ALTA DI AX
    	ADD BX,AX ;SOMMA DEI DUE REGISTRI 
    	
    	CMP CONTA,2 
    	JE FINE 
    	
    	JMP CICLO ;FINE DEL CICLO 
    FINE:
    	RET ;RESTITUISCO IL CONTROLLO AL MAIN 
    ENDP ;FINE DELLA PROCEDURA
    
    
    CALCOLO_AREA PROC NEAR
    
    	XOR DX,DX ;AZZERO IL REGISTRO DX 
    
    	;AREA DEL TRIANGOLO = (BASE * ALTEZZA) / 2 
    	
    	MOV AH,00H ;AZZERO LA PARTE ALTA DI AX 
    	MOV AL,BASE ;METTO IN AL LA BASE
    	MUL ALTEZZA ;MOLTIPLICO AX PER L'ALTEZZA 
    	DIV DUE ;DIVIDO IL REGISTRO AX PER 2 --> QUOZIENTE IN AL E IL RESTO IN AH 
    	MOV QUO,AX ;SALVO IL QUOZIENTE NELLA RISPETTIVA VARIABILE
    	
    	CMP DX,00H ;COMPARE FRA IL RESTO E AH 
    	JE FINE1;SE IL RESTO è UGUALE A ZERO(NON ESISTE) SALTO ALLA FINE DELLA PROCEDURA
    	MOV RESTO,DX  ;SALVO IL RESTO NELLA RISPETTIVA VARIABILE
    		
    	CMP DX,9 ;COMPARE FRA IL RESTO E 9 
    	JG CALCOLODECIM ;SE IL RESTO è PIù GRANDE DI 9 SALTA A "CALCOLODECIM"
    	
    	XOR AX,AX ;AZZERO IL REGISTRO AX 
    	MOV AX,RESTO ;METTO IN AL IL RESTO
    	MUL DIECI ;MOLTIPLICO PER 10 IL REGISTRO AX
    	MOV RESTO,AX ;SALVO IL RISULTATO NELLA VARIABILE RESTO
    	
    CALCOLODECIM:
    	XOR AX,AX ;AZZERO IL REGISTRO AX 
    	MOV AX,RESTO ;METTO IN AL IL RESTO
    	DIV DUE ;DIVIDO IL REGISTRO AX PER 2 --> QUOZIENTE IN AL E IL RESTO IN AH 
    	MOV DECIMALE,AX ;SALVO LA PARTE DECIMALE 
    		
    FINE1:	
    	RET ;RESTITUISCO IL CONTROLLO AL DOS 
    
    ENDP ;FINE DELLA PROCEDURA PER IL CALCOLODELL'AREA DEL TRIANGOLO
    
    STAMPARIS PROC NEAR
    	
    	XOR BX,BX ;AZZERO BX 
    	MOV CONTA,0  ;AZZERO LA VARIABILE CONTA 
    	MOV BX,DIECI ;METTO IN BX IL VALORE DELLA VARIABILE
    	
    CICLODIV: ;inizio del ciclo	
    
    	CMP AX,9 ;confronto il registro AX con 9 
    	JG DIVISIONE ;se il numero è maggiore di 9 significa che è almeno a due cifre quindi bisogna dividere per 10 
    	JLE NODIVISIONE ;se il numero è minore o uguale a nove si rappresenta di sicuro in un byte e salto il ciclo
    
    	DIVISIONE: 
    		MOV DH,00H
    		MOV DL,00H
    		;nel registro AX c'è il numero che devo dividere
    		DIV BX ;divido per 10 che è contenuto in BX --> AX QUOZIENTE E DX RESTO!!!
    		PUSH DX ;metto nello stack il resto della divisione che è contenuto in DX 
    		;non tocco il registro ax in quanto contiene già il probabile successivo numero che deve dividere
    		ADD CONTA,1 ;incremento la variabile contatore 
    		JMP CICLODIV ;salto incondizionato a "CICLODIV" così da ripetere il ciclo
    		
    	NODIVISIONE:
    		
    		MOV NUM,AL 
    		
    		CMP CONTA,0 
    		JZ STAMPA1 
    		JNZ STAMPA2
    		
    		STAMPA1:
    			MOV AH,02H ;richiesta per la stampa di un singolo carattere
    			MOV DL,NUM ;sposto in DL il carattere 
    			ADD DL,30H ;conversione 
    			INT 21H ;interrupt che permette di stampa il carattere
    			JMP EXIT ;salto incodizionato alla fine del programma
    			
    		STAMPA2:
    			
    			MOV AH,02H  ;richiesta per la stampa di un singolo carattere
    			MOV DL,NUM ;sposto in DL il carattere 
    			ADD DL,30H ;conversione 
    			INT 21H ;interrupt che permette di stampa il carattere
    			
    			XOR AX,AX ;azzero il registro AX per sicurezza
    			XOR BX,BX ;azzero il registro BX per sicurezza
    			
    		CICLOSTAMPA: ;ciclo per la stampa di un numero a più cifre
    			POP BX ;tiro fuori il numero dallo stack in DX 
    			MOV AH,02H ;richiesta per la stampa di un singolo carattere
    			MOV DL,BL
    			ADD DL,30H 
    			INT 21H 
    			SUB CONTA,1 ;decremento conta di 1 
    			CMP CONTA,0
    			JZ EXIT ;se la variabile conta è uguale a zero allora ha finito i numeri e quindi esco dal ciclo
    			JNZ CICLOSTAMPA ;se la variabile non è zero allora ricomincio il ciclo per la stampa 
    		
    EXIT:
    	RET 
    ENDP ;FINE DELLA PROCEDURA PER LA STAMPA DEL RISULTATO 
    
    CODE ENDS ;FINE DEL SEGMENTO DEL CODICE
    END INIZIO ;CHIUSURA ETICHETTA CHE INDICA L'INIZIO DEL PROGRAMMA
    Grazie e ciaoo
  • Re: Risultato errato[Risolto]

    Bene ... solo qualche consiglio per ottimizzare ...

    Non usare

    ADD CONTA,1

    ma

    INC CONTA

    e nel caso di queste linee

    JE FINE
    JMP CICLO ;FINE DEL CICLO
    FINE:

    al loro posto puoi scrivere

    JNE CICLO ;FINE DEL CICLO
    FINE:
  • Re: Risultato errato[Risolto]

    Grazie per i consigli
Devi accedere o registrarti per scrivere nel forum
5 risposte