Così li metti al contrario all'interno di EAX ... li stai inserendo cosi' AXX mentre dovrebbero essere DX:AX ...
Così li metti al contrario all'interno di EAX ... li stai inserendo cosi' AXX mentre dovrebbero essere DX:AX ...
si è vero scusami in realtà ho fatto così:
SHL EDX,16
xor dx,dx
MOV DX,AX
mov eax,edx
ma come ti dicevo si blocca quando và a fare la conversione in decimale...
Dato che utilizzi il registro EBP per la divisione e questo registro e' usato per la gestione dell'area delle variabili locali nello stack nelle chiamate delle funzioni, prova a salvarlo prima della divisione con
push ebp
e a ripristinarlo prima del return
pop ebp
ora nn si impalla piùma mi stampa un numero errato...ad esempio quando dovrebbe stampare 308025 mi stampa 264484...
A me funziona ... fai vedere il codice completo e corretto (quello che usi ...)
ecco quello completo:
.386
;Definizione costanti
PAGINA EQU 00h
HT EQU 09h
LF EQU 0Ah
CR EQU 0Dh
BIOS_VIDEO EQU 10H
SET_VIDEO_MODE EQU 00h;in AH
MODE_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
PRE_LEN EQU 10
DSEG SEGMENT PARA PUBLIC USE16 'DATA'
SEGNO DB ?
NUM DW 0
NUM_A2 DW 0
NUM_QUADR DD 0
DIVD DW ?
CONT DD 0
ERR_MESS DB CR,LF,LF,CR,'Valore non ammesso.Inserire un nuovo numero compreso tra -999 e 999:',0DH,0AH,'$'
TITOLO DB 'CORSO di CALCOLATORI ELETTRONICI$'
ISTRUZIONI DB CR,LF,LF,CR,'Inserire un numero compreso tra -999 e 999:$'
BIN_MESS DB CR,LF,HT,HT,'Rappresentazione Binaria:$'
A2_MESS DB CR,LF,HT,HT,'Rappresentazione Binaria in complemento A2:$'
DEC_MESS DB CR,LF,HT,HT,'Rappresentazione Decimale del quadrato del numero:$'
TERMINE DB CR,LF,LF,HT,'Un altra iterazione? [S/N]$'
CODICE_TASTO DB ?
DSEG ENDS
STACKM SEGMENT PARA STACK USE16 'STACK' ; Viene allocata una zona di
DB 64 DUP('12345678') ; memoria per lo stack: in
STACKM ENDS ; tutto 64*8 bytes.
ASSUME CS:CSEG,DSSEG,SS:STACKM
CSEG SEGMENT PARA PUBLIC USE16 'CODE'
;----------------------------------------------------------------------------------;
; Corpo principale del programma ;
;----------------------------------------------------------------------------------;
MAIN PROC FAR
PUSH DS ;Istruzioni da lasciare sempre
MOV AX,00h ; al principio dei programmi!
PUSH AX ;
CALL INIZIALIZZAZIONE
CICLO_PRINCIPALE: CALL PROMPT
CALL LETTURA_DATI
CALL STAMPA_BIN
CALL COMP_A2
CALL STAMPA_A2
CALL QUADR
CALL STAMPA_DEC
CALL TEST_FINALE
JNZ CICLO_PRINCIPALE
RET ;Ritorno al Sistema Operativo
MAIN ENDP
;----------------------------------------------------------------------------------;
; Procedura di inizializzazione ;
;----------------------------------------------------------------------------------;
INIZIALIZZAZIONE PROC NEAR
MOV AX,DSEG ;Inizializzazione segmento dati
MOV DS,AX ; tramite il registro AX.
MOV AH,SET_VIDEO_MODE ;Servizio BIOS 'Set Video Mode':
MOV AL,MODE_TESTO ;modo testo 80 x 25,colori
INT BIOS_VIDEO ;
MOV DX,0315h ;Imposta riga (DH) e colonna (DL)
CALL SPOSTA_CURSORE ;Muove il cursore nel pos scelta
MOV EDX,OFFSET TITOLO ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ;e la stampa.
MOV DX,0400h ;Imposta riga(DH) e colonna (DL)
CALL SPOSTA_CURSORE ;Muove il cursore nella pos scelta
RET ;Ritorno alla procedura chiamante
INIZIALIZZAZIONE ENDP
;-----------------------------------------------------------------------------------;
; Procedura per stampare il messaggio iniziale
;-----------------------------------------------------------------------------------;
PROMPT PROC NEAR
MOV EDX,OFFSET ISTRUZIONI ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ; e la stampa.
RET ;Ritorna alla procedura chiamante
PROMPT ENDP
;-----------------------------------------------------------------------------------;
; Procedura per stampare un numero in formato binario
;-----------------------------------------------------------------------------------;
STAMPA_BIN PROC NEAR
MOV EDX,OFFSET BIN_MESS ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ;e la stampa.
MOV DX,[NUM] ;Carica il numero inserito
MOV BL,10h ;Contatore di bits
CICLO_BINARIO: XOR AL,AL ;Azzera il registro AL
SHL DX,01h ;shift logico a Sinistra
ADC AL,AL ;In AL si pone il CARRY
CALL STAMPA_NUMERO ;Stampa cifra binaria
DEC BL ;Decrementa il contatore del ciclo
JNZ CICLO_BINARIO ;Se non é 0 itera un altra volta
RET ;Ritorno alla procedura chiamante
STAMPA_BIN ENDP
;-----------------------------------------------------------------------------------;
; Procedura per stampare in formato binario il numero in complemento a2 ;
;-----------------------------------------------------------------------------------;
STAMPA_A2 PROC NEAR
MOV EDX,OFFSET A2_MESS ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ;e la stampa.
CALL COMP_A2 ;Vado a complementare il numero
MOV DX,[NUM_A2] ;Carica il numero inserito
MOV BL,10h ;Contatore di bits
CICLO_BINARIO1: XOR AL,AL ;Azzera il registro AL
SHL DX,01h ;shift logico a Sinistra
ADC AL,AL ;In AL si pone il CARRY
CALL STAMPA_NUMERO ;Stampa cifra binaria
DEC BL ;Decrementa il contatore del ciclo
JNZ CICLO_BINARIO1 ;Se non é 0 itera un altra volta
RET ;Ritorno alla procedura chiamante
STAMPA_A2 ENDP
;-----------------------------------------------------------------------------------;
; Procedura per stampare un numero in formato decimale
;-----------------------------------------------------------------------------------;
STAMPA_DEC PROC NEAR
PUSH DX
MOV DX,OFFSET DEC_MESS ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ;e la stampa.
POP DX
push ebp
mov ebp,10 ; Destination base is decimal
xor cx,cx ; CX = 0, it will be our digit counter
DivideAgain:
xor edx,edx ; Clear high portion of dividend to prevent divide errors
div ebp ; EDX:EAX/EBP -> EAX r EDX
push dx ; Push the remainder (always 0-9) onto the stack
inc cx ; Increment the number of digits we know we have on the stack
test eax,eax ; Is the quotient from DIV zero?
jnz DivideAgain ; If not, then there are more digits to be extracted from the number, so loop
PrintMore:
pop ax ; Pop the next digit to be printed (0-9)
add al,"0" ; Convert it to an ASCII character ("0"-"9")
int 29h ; Print it
dec cx ; Decrement our counter of the number of digits we know are remaining on the stack
jnz PrintMore ; Zero? If not then we have more digits to print.
pop ebp
ret ; Return to the caller
STAMPA_DEC ENDP
;-----------------------------------------------------------------------------------;
; Procedura per fare il complemento A2 del numero inserito
;-----------------------------------------------------------------------------------;
COMP_A2 PROC NEAR
MOV SEGNO,0; azzero il flag del segno
MOV DX,[NUM];carico il numero inserito
NOT DX; ne faccio il complemento a1
ADD DX,1B;aggiungo 1 per fare il complemento a2
MOV NUM_A2,DX;
RET
COMP_A2 ENDP
;-----------------------------------------------------------------------------------;
; Procedura per fare il quadrato del numero inserito
;-----------------------------------------------------------------------------------;
QUADR PROC NEAR
MOV AX,NUM
MUL NUM; risultato della moltiplicazione in DX:AX
MOV D,DX
MOV A,AX
SHL EDX,16
xor dx,dx
MOV DX,AX
mov eax,edx
;MOV NUM_QUADR,EDX
RET
QUADR ENDP
;------------------------------------------------------------------------------------;
; Procedura per determinare se occorre un'altra iterazione
;------------------------------------------------------------------------------------;
TEST_FINALE PROC NEAR
MOV EDX,OFFSET TERMINE ;Sceglie la strinaga (DSX)
CALL STAMPA_STRINGA ;e la stampa.
CALL LETTURA_SN ;legge la stringa senza echo.
CMP AL,'n' ;modifica il FLAG 'Z'
RET ;Ritorno alla procedura chiamante
TEST_FINALE ENDP
;************************************************* ***********************************;
;* Procedura di basso livello di interfaccia *;
;************************************************* ***********************************;
;------------------------------------------------------------------------------------;
; Procedura per stampare un numero da 0 a 9
;------------------------------------------------------------------------------------;
STAMPA_NUMERO PROC NEAR
ADD AL,'0' ;La base da cui partire é '0'
MOV AH,W_CHR_TTY ;Servizio BIOS 'Write char in TTY'
INT BIOS_VIDEO
RET ;Ritorna alla procedura chiamante
STAMPA_NUMERO ENDP
;-----------------------------------------------------------------------------------;
; Procedura per leggere il numero immesso e memorizzarlo in BUFFER
;-----------------------------------------------------------------------------------;
LETTURA_DATI PROC NEAR
LAB0: XOR DX,DX
LAB1: MOV BX,10
MOV AH,08H ;legge un carattere senza echo
INT 21H
CMP AL,CR ;controlla è un invio?
JE FINE
CMP AL,'-'
JE MOD_SEGNO
CONTINUA: CMP AL,'0'
JB LAB1
CMP AL,'9'
JA LAB1
PUSH DX
MOV DL,AL
MOV AH,02H ;se ho premuto un numero lo stampo a video
INT 21H
POP DX
SUB AL,'0';sottrae la codifica di zero
XCHG AX,BX
XOR BH,BH
MUL DX;moltiplica per 10
MOV DX,AX
ADD DX,BX;somma la cifra letta
MOV NUM,DX
CMP NUM,999
JA I_ERR
JMP LAB1
I_ERR: LEA DX, ERR_MESS
MOV AH,9
INT 21H
JMP LAB0
MOD_SEGNO: MOV SEGNO,1
PUSH DX
MOV DL,AL
MOV AH,02H ;stampo il segno '-'
INT 21H
POP DX
JMP CONTINUA
COMPLEMENTA: MOV SEGNO,0
NOT NUM
ADD NUM,1B
JMP FINE
FINE: CMP SEGNO,1
JE COMPLEMENTA
RET
LETTURA_DATI ENDP
;------------------------------------------------------------------------------------;
; Procedura per leggere da tastiera uno dei tasti 'S' o 'N'
;------------------------------------------------------------------------------------;
LETTURA_SN PROC NEAR
NUOVA_LETTURA: MOV AH,R_KEY_CHR_NE ;Servizio DOS 'Read keyboard char'
INT DOS ;Whitout echo
OR AL,00100000b ;Converte in minuscolo
CMP AL,'n' ;Se il tasto premuto é 'N' esce
JZ FINE_LETTURA ;dalla procedura
CMP AL,'s' ;Se non é 's', ne legge
JNZ NUOVA_LETTURA ;un altro
FINE_LETTURA: RET
LETTURA_SN ENDP
;-----------------------------------------------------------------------------------;
; Procedura per spostare il cursore
;-----------------------------------------------------------------------------------;
SPOSTA_CURSORE PROC NEAR
MOV BH,PAGINA ;Pagina video attiva.
MOV AH,SET_CURSOR ;Servizio BIOS 'Set Cursor
INT BIOS_VIDEO ;Position'
RET ;Ritorno alla procedura chiamante
SPOSTA_CURSORE ENDP
;-----------------------------------------------------------------------------------;
; Procedura per stampare una stringa
STAMPA_STRINGA PROC NEAR
MOV AH,PRINT_STRING ;Servizio DOS 'Print String'; la
INT DOS ;stringa é puntata da DSX.
RET ;Ritorno alla procedura chiamante
STAMPA_STRINGA ENDP
CSEG ENDS
END MAIN
Questo lo cambierei così
codice:STAMPA_DEC PROC NEAR PUSH EAX MOV DX,OFFSET DEC_MESS ;Sceglie la stringa (DSX) CALL STAMPA_STRINGA ;e la stampa. POP EAX ...
Ora funziona perfettamente![]()
....grazie 1000 oregon!!!