Originariamente inviato da paolomail3
ma te ne intendi?...facciamo così ti dò la traccia:
![]()
Programmavo in assembly 8088 quando tu non eri nato ...
Se hai pazienza ti posso dare una mano ... altrimenti ...
Originariamente inviato da paolomail3
ma te ne intendi?...facciamo così ti dò la traccia:
![]()
Programmavo in assembly 8088 quando tu non eri nato ...
Se hai pazienza ti posso dare una mano ... altrimenti ...
ma nn importa il mio codice...voglio solo sapere come fare a copiare un numero di due cifre(esempio 16),che si trova in un registro AL,in una variabile DB oppure in elemento di un array DB.Tutto qua...mi riuscite a darmi l'istruzione corretta?
Un registro del tipo AL e' fatto da 8 bit ... non puoi dire che ci sono "2 cifre" ma che contiene valori compresi tra 0 e 255 ...
Se non siamo d'accordo su questo, non possiamo andare avanti ...
si sono d'accordo...io parlavo del mio caso,mi ritrovo ad avere in AL il giorno di due cifre e vorrei copiarlo ina variabile DB o in un elemento dell'array DB...inizialmente me lo fa fare solo che quando vado a stampare il contenuto della variabile o dell'array mi mette dei simboli a caso e ciò è dovuto al fatto che più di una cifra non riesce a metterle nella variabile o nel singolo elemento dell'array...capito cosa voglio dire?
No ... non ho capito ...
Tu dici "mi ritrovo ad avere in AL il giorno di due cifre " ... mi fai capire in quale formato e' questo giorno di due cifre in AL ?
Come lo copi "dato che te lo fa fare" in una variabile byte?
Mi sa che tu non hai chiari alcuni concetti di base e quindi non ci possiamo capire ...
Nel frattempo ho scritto questo pezzetto di codice che fa l'input, il controllo e la conversione delle date (manca ancora un controllo di validita' dei valori) ... dagli un'occhiata
codice:stk SEGMENT STACK DB 400H DUP(?) stk ENDS DSEG SEGMENT CR EQU 0DH LF EQU 0AH DOS EQU 21H BIOS_VIDEO EQU 10H SET_MODE EQU 00H RTN_DOS EQU 4CH BUFFINPUT EQU 0AH PRINT_STRING EQU 09H D1 DB 'Prima data: $' D2 DB 'Seconda data: $' DERR DB CR,LF,' ^ Data errata$' CRLF DB CR, LF, '$' GG1 DB ? MM1 DB ? AA1 DW ? GG2 DB ? MM2 DB ? AA2 DW ? HLINE DB 80, 0 LINE DB 80 DUP(0) DSEG ENDS ASSUME CS:SEG CSEG, DS:SEG DSEG, SS:SEG stk CSEG SEGMENT 'CODE' main: MOV AX,SEG DSEG MOV DS,AX MOV AH, SET_MODE MOV AL, 03H INT BIOS_VIDEO MOV DX, OFFSET D1 MOV DI, OFFSET GG1 CALL INCHECKDATE MOV DX, OFFSET D2 MOV DI, OFFSET GG2 CALL INCHECKDATE ; Interrompere il programma se le date sono sbagliate? MOV AH, RTN_DOS INT DOS ;;;;;;;;;;;;;;;;;;;;;;;; INCHECKDATE PROC NEAR CALL STRINGOUT MOV AH, BUFFINPUT MOV DX, OFFSET HLINE INT DOS MOV SI, OFFSET LINE MOV CL,[SI-1] CMP CL,10 JNZ DATERR ADD SI,9 CKLOOP: MOV AL,[SI] CMP CL,3 JZ CKSL CMP CL,6 JZ CKSL CALL CHECKDIGIT JC DATERR AND AL,0FH MOV [SI],AL JNC NXT CKSL: CMP AL,'/' JNZ DATERR NXT: DEC SI DEC CL JNZ CKLOOP ; Data ok MOV CX,10 MOV AX,0 MOV AL,[SI+1] IMUL CX ADD AL,[SI+2] MOV [DI],AL ; Conversione MOV AX,0 MOV AL,[SI+4] IMUL CX ADD AL,[SI+5] MOV [DI+1],AL MOV AX,0 MOV CX,1000 MOV AL,[SI+7] IMUL CX MOV BX,AX MOV CX,100 MOV AX,0 MOV AL,[SI+8] IMUL CX ADD BX,AX MOV CX,100 MOV AX,0 MOV AL,[SI+9] IMUL CX ADD BX,AX MOV AX,0 MOV AL,[SI+10] ADD BX,AX MOV [DI+2],BX MOV DX, OFFSET CRLF CALL STRINGOUT RET DATERR: MOV DX, OFFSET DERR CALL STRINGOUT MOV DX, OFFSET CRLF CALL STRINGOUT RET INCHECKDATE ENDP CHECKDIGIT PROC NEAR CMP AL,'0' JL EXCK CMP AL,'9' JG EXCK CLC RET EXCK: STC RET CHECKDIGIT ENDP STRINGOUT PROC NEAR MOV AH,PRINT_STRING INT DOS RET STRINGOUT ENDP CSEG ENDS END main
grazie,sei molto gentile e si vede che te ne intendi...ci sono diversi comandi però che non conosco...se mi risolvi questa lacuna immensa che ho te ne sono grato e risolviamo tutto:io
mi ritrovo ad avere in AL o BH o CL,qualunque registro di 8 bit il giorno che l'utente ha inserito nella data ok?Adesso vorrei copiare il contenuto di questi registri in un 'qualcosa' che contenga quel valore...ora non so la dimensione del giorno contenuto in quel registro perchè,ma so per certo che se vado a copiarlo in una variabile di DB o in un elemento di un array DB mi inserisce dei simboli a caso...invece se il giorno contenuto in AL è di una sola cifra me lo copia nella variabile DB o nell'array DB in modo corretto....in pratica faccio questo:
GIORNO DB ?
......
MOV AH, READ_CHAR ;leggo un carattere dalla tastiera
INT DOS
CMP AL, CR ;è = a return ?
JE fine_lettura ;se si smetto di leggere
MOV sorgente[SI], AL;sposto il carattere in sorgente
;vado avanti così e riempio l'array sorgente...poi faccio questo
MOV BH,sorgente[SI] ;copio la prima cifra di sorgente(ke sarebbe il primo carattere inserito dall'utente)
MOV AL,sorgente[SI+1];e la seconda
CMP BH,'0'
JE giorno0
CMP BH,'1'
JE giorno1
CMP BH,'2'
JE giorno2
CMP BH,'3'
JE giorno3
;ora mi calcolo il giorno e lo metto in AL
giorno0:
MOV GIORNO,AL ;|||||||||QUI è IL PROBLEMA||||DOVE METTO IL VALORE DI AL??se lo metto nella variabile 'GIORNO DB',me lo compila ma mi mette dei valori a caso,ke posso usare come memoria???arry qualsiasi cosa ke possa contenere quel valore...
RET
giorno1:
ADD AL, 10
MOV GIORNO,AL ;|||||||||ANKE QUI è IL PROBLEMA||||DOVE METTO IL VALORE DI AL??
RET
giorno2:
ADD AL,20
MOV GIORNO,AL ;|||||||||ANKE QUI è IL PROBLEMA||||DOVE METTO IL VALORE DI AL??
giorno3:
ADD AL,30
MOV GIORNO,AL ;|||||||||ANKE QUI è IL PROBLEMA||||DOVE METTO IL VALORE DI AL??
RET
spero che mi abbia capito e che questa volta riesci a risolvere,grazie ancora comunque...
Allora, anche se e' tutto pronto nel codice che ti ho scritto (e c'e' anche la risposta a tutti i tuoi quesiti), procediamo con il tuo codice ...
Cominciamo con l'istruzione
MOV GIORNO,AL
che e' corretta. Ma tu dici che ti inserisce "valori a caso" ...
Considera che tu prendi la prima cifra (quella delle decine, in BH) e in base a quella aggiungi 10, 20 o 30 a quella delle unita' (che hai in AL ... io uso la IMUL, moltiplicazione, nel mio codice ... ma lasciamo perdere ...).
Il problema e' forse nell'addizione ... Considera infatti che in AL il valore della cifra dell'unita' e' codificata in ASCII, mentre tu la tratti come se fosse binaria. Per capirci, ti faccio un esempio
Se hai inserito il valore 15 per il giorno, avrai
in BH il valore ASCII del carattere '1' ovvero 31H
in AL il valore ASCII del carattere '5' ovvero 35H
Dal confronto con BH, tu vai ad eseguire la riga
ADD AL, 10
e quindi, dopo aver convertito tutto in decimale, farai una somma tra
10 e 53 = 63
che non c'entra nulla con il 15 di partenza.
La soluzione e' considerare solamente i 4 bit meno significativi di AL per l'unita'.
Questo lo ottieni scrivendo subito dopo la riga
MOV AL,sorgente[SI+1];
la riga
AND AL,0FH
In questo modo, nell'esempio precedente avrai che il 35H viene trasformato in 05H e sommato al 10 ti dara' il valore corretto (15 in decimale, ovvero 0FH esadecimale) nella variabile GIORNO.
In definitiva, non c'entrava nulla la "grandezza" della variabile GIORNO, ne' avevi due cifre in AL come dicevi ... era solamente un problema di "CONVERSIONE ASCII - BINARIO".
solo due ultime cose poi ti lascio in pace,promesso...
quindi se voglio convertire qualunque valore ascii in esadecimale uso 'AND 0FH'??ke bello
e poi un'ultima cosa ora che ho la variabile GIORNO DB con il giusto valore,mi dici l'istruzione per stamparla in modo da controllare se il valore è giusto?per caso si fa così:
MOV DX, OFFSET GIORNO
CALL STAMPA_STRINGA
MOV AX,SEG DSEG ;Inizializzazione segmento dati
MOV DS,AX ;tramite il registro AX.
MOV AH,09H ;Servizio DOS 'Print String'; la
INT 21H ;stringa e' puntata da DSX.
RET
ti ho fatto quest'ultima domanda perchè se è come dici tu,anche prima metteva il valore 63(ke era sbagliato),non avrebbe dovuto stamparmi dei simboli a caso,avrebbe dovuto stamparmi 63,o no?
No ... non proprio ...Originariamente inviato da paolomail3
quindi se voglio convertire qualunque valore ascii in esadecimale uso 'AND 0FH'??ke bello![]()
Solo se devi convertire un carattere che rappresenta una cifra (da '0' a '9' per intenderci).
Questi caratteri hanno valore ASCII compreso tra 30H e 39H e la AND trasforma il valore nel range 0 ... 9
Per altri caratteri, ovviamente, questa conversione non ha senso.
No ... non si fa cosi' ... ti visualizzerebbe il corrispondente carattere della tabella ASCII.e poi un'ultima cosa ora che ho la variabile GIORNO DB con il giusto valore,mi dici l'istruzione per stamparla in modo da controllare se il valore è giusto?per caso si fa così: ...
Supponi di avere il valore 15, ti visualizzera' il carattere ASCII 15 (probabilmente un simbolo senza significato).
Per visualizzare il numero, dovrai fare le operazioni inverse (conversione da binario ad ASCII). Ti indico i "passi" (con il 15) ... ma li dovrai sviluppare tu ...
- Dividi il valore 15 per 10 (o usi la sottrazione ... ricorda che tante sottrazioni sono come una divisione) e ottieni la parte intera del risultato, ovvero 1
- Esegui una OR tra questo valore e la costante 30H (ottieni 31H)
- Visualizza il carattere ASCII ottenuto
- Prendi la differenza tra 15 e 1*10 (ovvero 15-10=5)
- Esegui una OR tra questo valore e la costante 30H (ottieni 35H)
- Visualizza il carattere ASCII ottenuto
No ... ti avrebbe stampato il carattere ASCII corrispondente al numero 63, ovvero un punto interrogativo (prova con il tastierino numerico ALT+63)ti ho fatto quest'ultima domanda perchè se è come dici tu,anche prima metteva il valore 63(ke era sbagliato),non avrebbe dovuto stamparmi dei simboli a caso,avrebbe dovuto stamparmi 63,o no?
ho capito...ma non ho una certa dimestichezza con le divisioni in assembler,mi potresti scrivere tu la parte del codice per stampare il valore (anche 15) della variabile GIORNO DB ?grazie ancora