PDA

View Full Version : [Assembler 8086]Stampa array caratteri da input


kwb
11-11-2010, 11:18
Ciao, ho provato a fare questo programma che, presi in input dei caratteri, li stampa a schermo.
La mia idea era quella di fermare l'input quando davo invio ( la nuova riga per intenderci ), oppure quando il vettore era riempito... Però sorgono alcuni problemi.
Prima il codice:

.MODEL SMALL
.STACK
.DATA

DIM EQU 11
VETT DB DIM DUP (?)
DIME DB 0

.CODE
.STARTUP

MOV AH,1 ;Preparo AH per la lettura
MOV AL,0 ;Azzero AL
MOV DI,0 ;DI e
MOV CX,DIM ;CX

label1: INT 21H ;Leggo l'input
MOV VETT[DI], AL ;E lo sposto in VETT[DI]
CMP AL, 0AH ;Guardo se AL e' uguale a '\n'
JZ label2 ;Salto a label 2 se lo è
INC DIME ;Altrimenti incremento DIME, una variabile di supporto per l'indice
INC DI ;Incremento DI, l'indice
LOOP label1 ;Continuo finchè CX non e' uguale a 0
label2: MOV AH,2 ;Preparo AH per stampare l'output
MOV DI,0 ;Azzero DI
MOV DL,0 ;Azzero DL, usato per la scrittura
MOV CX,0 ;Azzero CX
MOV CL,DIME ;Sposto il valore in DIME ( che corrisponde agli elementi totali inseriti ) dentro CX
print: MOV DL,VETT[DI] ;Sposto i singoli elementi di VETT[DI] in DL
INT 21H ;Stampo
INC DI ;Aumento DI
LOOP print ;Mi fermo quando CX e' uguale a 0
.EXIT
END

Uno dei problemi è: ho utilizzato una variabile per tenere traccia di quanti caratteri ho inserito, nel caso non arrivassi fino al riempimento totale del vettore. Tuttavia, quando do enter, il vettore viene riempito con 0Dh, ovvero il Carriage Return ( così dice la mia ascii table )... Perchè? Io vorrei che quando do enter venga riempito con 0Ah, la new line... Certo posso tranquillamente cambiare il tipo di controllo e dire al programma di controllare che in AL non ci sia 0Dh per continuare... Però volevo capire perchè c'è questa diversità tra C e Assembler...
Inoltre, avendo definito DIME come byte, se provo a metterlo dentro CX il compilatore mi da errore... Ci sono problemi se uso CL invece che CX? Posso usarlo per tenere traccia del massimo numero di elementi che ho inserito ( un po' come quando metto una costante dentro CX )?

Grazie

kwb
11-11-2010, 18:46
Ok ho visto che il carattere di nuova riga è il carriage return, cmq qualcosa non va perchè poi non mi stampa niente... I caratteri vengono messi correttamente dentro il registro DL, è l'int 21h che ha qualche problema che non mi torna...

Supdario
11-11-2010, 21:42
Ciao, ho provato a fare questo programma che, presi in input dei caratteri, li stampa a schermo.
La mia idea era quella di fermare l'input quando davo invio ( la nuova riga per intenderci ), oppure quando il vettore era riempito... Però sorgono alcuni problemi.
Prima il codice:

.MODEL SMALL
.STACK
.DATA

DIM EQU 11
VETT DB DIM DUP (?)
DIME DB 0

.CODE
.STARTUP

MOV AH,1 ;Preparo AH per la lettura
MOV AL,0 ;Azzero AL
MOV DI,0 ;DI e
MOV CX,DIM ;CX

label1: INT 21H ;Leggo l'input
MOV VETT[DI], AL ;E lo sposto in VETT[DI]
CMP AL, 0AH ;Guardo se AL e' uguale a '\n'
JZ label2 ;Salto a label 2 se lo è
INC DIME ;Altrimenti incremento DIME, una variabile di supporto per l'indice
INC DI ;Incremento DI, l'indice
LOOP label1 ;Continuo finchè CX non e' uguale a 0
label2: MOV AH,2 ;Preparo AH per stampare l'output
MOV DI,0 ;Azzero DI
MOV DL,0 ;Azzero DL, usato per la scrittura
MOV CX,0 ;Azzero CX
MOV CL,DIME ;Sposto il valore in DIME ( che corrisponde agli elementi totali inseriti ) dentro CX
print: MOV DL,VETT[DI] ;Sposto i singoli elementi di VETT[DI] in DL
INT 21H ;Stampo
INC DI ;Aumento DI
LOOP print ;Mi fermo quando CX e' uguale a 0
.EXIT
END

Uno dei problemi è: ho utilizzato una variabile per tenere traccia di quanti caratteri ho inserito, nel caso non arrivassi fino al riempimento totale del vettore. Tuttavia, quando do enter, il vettore viene riempito con 0Dh, ovvero il Carriage Return ( così dice la mia ascii table )... Perchè? Io vorrei che quando do enter venga riempito con 0Ah, la new line... Certo posso tranquillamente cambiare il tipo di controllo e dire al programma di controllare che in AL non ci sia 0Dh per continuare... Però volevo capire perchè c'è questa diversità tra C e Assembler...
Inoltre, avendo definito DIME come byte, se provo a metterlo dentro CX il compilatore mi da errore... Ci sono problemi se uso CL invece che CX? Posso usarlo per tenere traccia del massimo numero di elementi che ho inserito ( un po' come quando metto una costante dentro CX )?

Grazie

Su Windows l'a capo è \r\n (0Dh, 0Ah), mentre sui sistemi operativi Unix-Like è solo \n.
Probabilmente il tuo programma è progettato per prendere un solo carattere, quindi prende il primo che trova, che è \r.

Per la seconda domanda, se definisci una variabile come byte (8bit), non puoi copiarla in un registro a 16bit. Al massimo o la definisci come word, oppure la copi sia in cl che in ch.

kwb
11-11-2010, 22:21
Su Windows l'a capo è \r\n (0Dh, 0Ah), mentre sui sistemi operativi Unix-Like è solo \n.
Probabilmente il tuo programma è progettato per prendere un solo carattere, quindi prende il primo che trova, che è \r.Ah capito, allora troverò un modo per aggiungerci un 0Ah alla fine...


Per la seconda domanda, se definisci una variabile come byte (8bit), non puoi copiarla in un registro a 16bit. Al massimo o la definisci come word, oppure la copi sia in cl che in ch.Si... Alla fine ho caricato la variabile da 8 bit nel CL... Il mio timore era che istruzioni come LOOP funzionassero solo su CX, e che non fossero in grado di decrementare parte di CX, cosa che mi sbagliavo. Ho controllato dal debugger e il decremento di CL funziona correttamente.

kwb
12-11-2010, 09:52
Non riesco a venirne a capo:

.MODEL SMALL
.STACK
.DATA

DIM EQU 11
VETT DB DIM DUP (?)
DIME DB 0

.CODE
.STARTUP

MOV AH,1 ;Preparo AH per la lettura
MOV AL,0 ;Azzero AL
MOV DI,0 ;DI e
MOV CX,DIM ;CX

label1: INT 21H ;Leggo l'input
CMP AL, 0DH ;Guardo se AL e' uguale al carriage return
JZ label2 ;Salto a label 2 se lo è
MOV VETT[DI], AL ;E lo sposto in VETT[DI]
INC DIME ;Altrimenti incremento DIME, una variabile di supporto per l'indice
INC DI ;Incremento DI, l'indice
LOOP label1 ;Continuo finchè CX non e' uguale a 0
label2: MOV AL, 0AH ;Metto il new line dentro al
MOV AH,2 ;Preparo AH per stampare l'output
MOV DI,0 ;Azzero DI
MOV DX,0 ;Azzero DX, in particolare DL, usato per la scrittura
MOV CX,0 ;Azzero CX
MOV CL,DIME ;Sposto il valore in DIME ( che corrisponde agli elementi totali inseriti ) dentro CX
print: MOV DL,VETT[DI] ;Sposto i singoli elementi di VETT[DI] in DL
INT 21H ;Stampo
INC DI ;Aumento DI
LOOP print ;Mi fermo quando CX e' uguale a 0
.EXIT
END


Ho detto al programma di fermarsi col carriage return, e successivamente, di inserire in AL la new line... Però continua a non stampare, dove sta il problema???

kwb
13-11-2010, 16:06
Ho scoperto dove stava il problema. Il programma funziona benissimo, solo che stampava sulla stessa riga e sugli stessi caratteri, quindi io non vedevo nessun cambiamento.
È bastato far stampare un CR e LF così da poter vedere il risultato su una nuova riga.:D