Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [Assembly 8086 tasm] Problema di overflow

    Buon pomeriggio.
    Devo svolgere un progetto che stampi le potenze di 2 comprese tra A e B, che possono andare da 0 a 64000.
    Il progetto l'ho svolto senza problemi, mi segnala gli errori necessari (se supero 64000), ma l'errore non mi viene più segnalato se digito 65535 o superiori. Dev'esserci un problema di overflow che non so come correggere. Potreste darmi una mano?
    Grazie in anticipo.
    codice:
    PAGINA   EQU      00h
    HT  	     EQU   	09h
    LF  	     EQU   	0Ah
    CR	     EQU   	0Dh
    BIOS_VIDEO     EQU		10H
    SET_VIDEO_MODE     EQU		00h 		;in AH
    MODO_TESTO	     EQU		03H	        ;in AL
    SET_CURSOR	     EQU		02h 		;in AH
    W_CHR_TTY	     EQU		0Eh  		;in AH
    DOS		      EQU		21H
    R_KEY_CHR       EQU		01H
    PRINT_STRING	EQU		09H
    R_KEY_CHR_NE 	EQU		07h 
    DSEG            SEGMENT PARA PUBLIC 'DATA'
    NCIFRE          EQU     8
    ARRAY1          DB      NCIFRE DUP(?)
    ARRAY2          DB      NCIFRE DUP(?)
    RIS             DB      NCIFRE+1 DUP(?),'$'
    NUMERO1         DW      00
    NUMERO2         DW      00
    DSEG            ENDS
    STACKM     SEGMENT PARA STACK 'STACK'  ;Viene allocata una zona di
                    DB      64 DUP('12345678')  ; memoria per lo Stack: in
    STACKM          ENDS                        ; tutto 64*8 bytes.
    ASSUME CS:CSEG,DS:DSEG,SS:STACKM
    CSEG            SEGMENT PARA PUBLIC 'CODE'
    ;Procedura per leggere un numero e memorizzarlo in NUMERO1
    LETTURA_DATI1  PROC  NEAR
                   XOR   CL,CL  ;Azzero CL
    	       XOR   BX,BX  ;Azzero BX
    	       XOR   AX,AX  ;Azzero AX
    	       MOV   SI,0    ;Mi posiziono nella prima locazione dell'array
    START1:        MOV   AH,01H	;Servizio DOS 'Read Keyboard Char'
               INT   DOS             		   
    	   CMP   AL,13   ;Confronto che il numero non sia il tasto "INVIO"
    	   JE    FLETTURA  ;se sì, salto a FLETTURA
    	   CMP   AL, '0'     ;Controllo che i caratteri inseriti siano numeri
    	   JB    ERRORE
    	   CMP   AL, '9'     ;e non lettere.
    	   JA    ERRORE
    MEM1: 	   SUB   AL,'0'          
    	   MOV   BYTE PTR ARRAY1[SI],AL
    	   INC   SI   ;Incremento l'indice dell'array
    	   INC   CL   ;Incremento il contatore delle cifre
               JMP   START1	
    FLETTURA:    MOV  ARRAY1[SI+1],'$' ;Inserisco il carattere di fine stringa alla fine
               XOR   AX,AX ;Azzero i registri
    	   XOR   DX,DX
    	   XOR   BX,BX
    	   MOV   SI, OFFSET ARRAY1
    CICLO:	   MOV   AX,[BX+SI]
    	   XOR   DX,DX
    	   XOR   AH,AH
    	   CMP   AX,'$'    ;Confronto per verificare se è la fine della stringa
    	   JE    FINE            ;se sì, salto a FINE
    	   CMP   CL, 1           ;Confronto se il contatore di cifre è uguale a 1
    	   JE    FINE            ;se sì, salto a FINE
    	   ADD   AX,[NUMERO1]    ;Sommo NUMERO_1 in AX
    	   MOV   DX, 10          
    	   MUL   DX              ;Moltiplico NUMERO_1 per 10
    	   DEC   CL              ;Decremento CL (solo in caso di CL>1)
    	   INC   BX              ;incremento l'indice dell'array
    	   MOV  [NUMERO1],AX     ;Sommo il numero moltiplicato in NUMERO_1
              JMP   CICLO           ;Ripeto il ciclo, fino ad avere CL=1
    				   
    ERRORE:    MOV   DX,OFFSET MESS_ERR  ;Stampa il "messaggio d'errore" 
               CALL  STAMPA_STRINGA
    	   CALL PROMPT_1
               XOR   CL,CL           ;Azzero CL
    	   XOR   BX,BX           ;Azzero BX
    	   XOR   AX,AX           ;Azzero AX
               MOV   SI,0
    	   MOV	[NUMERO1],00     ;Azzero NUMERO1
               JMP   START1	
     FINE:   ADD   [NUMERO1],AX    ;Sovvrascrivo AX in NUMERO_1
    	   JMP   CONTROLLO1      ;Controllo finale
    		   
    CONTROLLO1:    XOR   DX,DX
    	   MOV   DX, 64000
    	   CMP   DX, [NUMERO1]   ;Confronto 64000 con NUMERO1
    	   JB    ERRORE_1        ;se minore, stampa messaggio d'errore
    	   JMP   FINE_FINE
    
    ERRORE_1:  MOV   DX, OFFSET MEX_ERR
    	    CALL  STAMPA_STRINGA  ;Stampa "messaggio d'errore" sulle cifre > 64000
    	    CALL  PROMPT_1
                XOR   CL,CL           ;Azzero CL
    	    XOR   BX,BX           ;Azzero BX
    	    XOR   AX,AX           ;Azzero AX
    	    MOV   SI,0
    	    MOV	[NUMERO1],00     ;Azzero NUMERO1
    	    JMP   START1	
    FINE_FINE: RET
    LETTURA_DATI1      ENDP
    
    ;Procedura per leggere un numero e memorizzarlo in NUMERO2
    LETTURA_DATI2      PROC  NEAR
                XOR   CL,CL 
    	    XOR   BX,BX
    	    XOR   AX,AX
    	    MOV   SI,0
    START2:    MOV   AH,01H   ;Servizio DOS 'Read Keyboard Char'
                INT   DOS             	   
                CMP   AL,13   ;Confronto che il numero non sia il tasto "INVIO"
    	    JE    FLETTURA2				   
    	    CMP   AL, '0'    ;Confronto che i caratteri inseriti siano numeri
    	    JB    ERRORE2
    	    CMP   AL, '9'    ;e non lettere.
    	    JA    ERRORE2
    MEM2:      SUB   AL,'0'
    	   MOV   BYTE PTR ARRAY2[SI],AL
    	   INC   SI      ;Incremento l'indice dell'array
    	   INC   CL      ;Incremento il contatore delle cifre
              JMP   START2	
    FLETTURA2:   MOV  ARRAY2[SI+1],'$' ;Inserisco il carattere di fine stringa alla fine
               XOR   AX,AX
    	   XOR   DX,DX
    	   XOR   BX,BX
    	   MOV   SI, OFFSET ARRAY2
    CICLO2:	   MOV   AX,[BX+SI]  ;Mi sposto di un posto
    	   XOR   AH,AH
    	   XOR   DX,DX
    	   CMP   AX,'$'   ;Confronto per verificare se è la fine della stringa
    	   JE    FINE2    ;se sì, salto a FINE2
    	   CMP   CL,1    ;Confronto se il contatore delle cifre è uguale a 1
    	   JE    FINE2           ;se sì, salto a FINE2
    	   ADD   AX,[NUMERO2]    ;Sommo NUMERO_2 in AX
    	   MOV   DX,10
    	   MUL   DX     ;Moltiplico NUMERO_2 per 10
    	   DEC   CL      ;Decremento CL (solo in caso di CL>1)
    	   INC   BX       ;incremento l'indice dell'array
    	   MOV  [NUMERO2],AX     ;Sommo il numero moltiplicato in NUMERO_2
    	   JMP   CICLO2          ;Ripeto il ciclo, fino ad avere CL=1
    ERRORE2:    MOV   DX,OFFSET MESS_ERR
               CALL  STAMPA_STRINGA  ;Stampa messaggio d'errore
    	   CALL  PROMPT_2
               XOR   CL,CL 
    	   XOR   BX,BX
    	   XOR   AX,AX
    	   MOV   SI,0
    	   MOV	[NUMERO2],00     ;Azzero NUMERO1
               JMP   START2
    FINE2:  ADD  [NUMERO2],AX     ;Sovrascrivo AX in NUMERO2
    	   JMP  CONTROLLO2       ;Controllo finale
    CONTROLLO2:    XOR   DX,DX
                MOV   DX, 64000
    	    CMP   DX, [NUMERO2]   ;Confronto 64000 con NUMERO2
    	    JB    ERRORE_2        ;stampa messaggio d'errore
    	    JMP   FINE_FINE2
    ERRORE_2:      MOV   DX, OFFSET MEX_ERR
    	    CALL  STAMPA_STRINGA  ;Stampa messaggio d'errore sulle cifre > 64000
    	    CALL  PROMPT_2
                XOR   CL,CL 
                XOR   BX,BX
    	    XOR   AX,AX
    	    MOV   SI,0
    	    MOV	[NUMERO2],00 ;Azzero NUMERO2
    	    JMP   START2
    FINE_FINE2:    RET
    LETTURA_DATI2      ENDP
    
    ;PROCEDURA PER DETERMINARE LE POTENZE DI 2 
    POTENZA     PROC NEAR
    INIZIO:    XOR AX, AX   ;Azzero i registri
    	    XOR BX, BX
    	    XOR CX, CX
    	    XOR DX, DX
    	    MOV AX, [NUMERO1]    ;Sposto NUMERO_1 nel registro AX (16 bit)
                MOV BX, [NUMERO2]    ;Sposto NUMERO_2 nel registro BX (16 bit)
    	    INC BX       ;Incrementando BX, se NUMERO_2 è potenza di 2, viene stampata
    	    CMP AX, BX      ;Confronto di ugualianza
    	    JE FINEPOT      ;Se i numeri sono uguali, salto a FINEPOT
    	    MOV CX, 2         ;Imposto il divisore
    DIVID:	DIV CX                       
    	    CMP DX, 0       ;Confronto il resto con 0
    	    JNE FINEPOT1    ;se non è uguale, salto a FINEPOT1
    	    CMP AX, 0         ;Confronto il risultato con 0
    	    JE  FINEPOT1    ;se è uguale, salto a FINEPOT1
    	    CMP AX, 1      ;Confronto il risultato con 1
    	    JA  DIVID        ;se maggiore, ripeto DIVID
                CALL STAMPA_DEC
    	    MOV   AL,' '    ;Stampa spazio
                MOV   AH,W_CHR_TTY   ;Servizio BIOS 'Write Char in TTY'
                INT   BIOS_VIDEO
    FINEPOT1:   INC NUMERO1   ;Prendo in esame il numero successivo
                JMP INIZIO	    ;Ripeto da INIZIO
    FINEPOT:    RET
    POTENZA     ENDP
    
    CSEG              ENDS
                      END  MAIN

  2. #2
    Semplicemente, NUMERO1 o le variabili in cui metti il numero, sono DW, quindi Double...2 byte. Il limite intero che puoi mettere in esse sarà appunto 65mila ecc ecc...è un limite "fisico", nn puoi aggirarlo a meno di avere un qualcosa piu grande del DW

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Originariamente inviato da celtico94
    sono DW, quindi Double...2 byte.
    Il problema è quello, ma DW significa Define Word e non Double ...

    Una Word è appunto costituita da due byte (16 bit) e avrai problemi oltre il valore massimo (65535).

    Puoi utilizzare, appunto, una Double Word e quindi scriverai

    DD

    Define Doubleword

    in modo da gestire 32 bit e circa 4 miliardi come valore massimo.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  4. #4
    Molto gentili grazie!
    Chiedo scusa per quest'altra domanda elementare, ma è solo il secondo assegnamento che svolgo in assembly.
    Una volta messo DD a NUMERO1 e NUMERO2, cos'altro devo modificare??
    Escono errori "gli operandi non corrispondono"

  5. #5
    Ovvio perche ora lavori con variabili a 4byte, quidi anche nelle operazioni devi usare o registri maggiori(non credo esistano nell'8086) o altro algoritmo per gestire piu bit all'interno

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.