salve a tutti, ho un problema con un progetto da sviluppare in assembler....il progetto in breve, è questo:
il programma riceve in ingresso una stringa la cui lunghezza max è 80 caratteri. Letta la stringa la converte in binario e stampa a video il risultato della conversione.
la fase problematica è la fase di conversione della stringa in binario, in quanto riesco a convertire solo l'ultimo carattere. Il sorgente l'ho impostato in questa maniera:
;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
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'
TITOLO DB 'PROGETTO1$'
ISTRUZIONI DB CR,HT,HT,HT,HT,HT,CR,'Inserire una stringa:$'
BIN_MESS DB CR,LF,HT,HT,'Rappresentazione Binaria: $'
PUNTO DB CR,LF,HT,HT, '.$'
TERMINE DB CR,LF,LF,HT,'Un''altra iterazione? [S/N] $'
ENTER EQU 13
MAX_LUNGH EQU 80
CODICE_TASTO DB MAX_LUNGH DUP(?) ;Sequenza di MAX_LUNGH
LUNGH_SEQU DW ? ;Lunghezza della stringa
PAGIN EQU 00h
INDEX DW MAX_LUNGH DUP(?)
SEQUENZA DB ?
DSEG ENDS
STACKM SEGMENT PARA STACK 'STACK' ; Viene allocata una zona
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 '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_STRINGA
CALL STAMPA_BIN
CALL TEST_FINALE
JNZ CICLO_PRINCIPALE
RET
MAIN ENDP
;-----------------------------------------------------------------------;
; Procedura di inizializzazione ;
; ;
;REGISTRI UTILIZZATI: AX, DX, DS ;
;-----------------------------------------------------------------------;
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,MODO_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 nella pos scelta
MOV DX,OFFSET TITOLO ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ; e la stampa.
MOV DX,0909h ;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 ;
; ;
; REGISTRI UTILIZZATI: DX, AH ;
;-----------------------------------------------------------------------;
PROMPT PROC NEAR
MOV DX,OFFSET ISTRUZIONI ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ; e la stampa.
RET ;Ritorno alla procedura chiamante
PROMPT ENDP
;-----------------------------------------------------------------------;
; Procedura per leggere una stringa e memorizzarla in BX ;
; ;
;PARAMETRI: La stringa e' memorizzata in BX ;
;REGISTRI UTILIZZATI: AX,BX,CX,DL ;
;-----------------------------------------------------------------------;
LETTURA_STRINGA PROC NEAR
MOV CX,00h
MOV CX,MAX_LUNGH ;inizializza il contatore caratteri
NUOVA_LETT: MOV AH,08h ;servizio DOS 'Read Keyboard Char
INT 21h ;Without Echo'
CMP AL,ENTER ;se il tasto è ENTER,
JZ FINE_LETTURA ;termina la lettura
PUSH AX ;salva il registro AX
MOV AH,02h ;servizio DOS 'Character Output'
MOV DL,AL ;Carattere da stampare
INT 21h
POP AX ;ripristina il contenuto di AX
MOV [CODICE_TASTO],AL ;Memorizza il tasto
INC BX ;Aggiorna il puntatore
LOOP NUOVA_LETT ;reitera fino a che CX=0
FINE_LETTURA: MOV [LUNGH_SEQU],BX
RET
LETTURA_STRINGA ENDP
STAMPA_BIN PROC NEAR
MOV DX,OFFSET BIN_MESS
CALL STAMPA_STRINGA
MOV BX,0
NEW: MOV DL,[CODICE_TASTO] ;LEGGE IL CODICE DEL TASTO
PUSH BX
MOV BX,[INDEX]
MOV [SEQUENZA+BX],DL
POP BX
INC BX
INC INDEX
MOV DH,00h ;CONTATORE DI BITS
CICLO_BINARIO: XOR AL,AL
SHL DL,01h
ADC AL,AL
CALL STAMPA_NUMERO
INC DH
JNZ CICLO_BINARIO
; CMP BX,[LUNGH_SEQU]
RET
STAMPA_BIN ENDP
;-----------------------------------------------------------------------;
; Procedura per determinare se occorre un'altra iterazione ;
; ;
; EGISTRI UTILIZZATI: AX, DX ;
; CODICI DI RITORNO: ;
; Zero flg = 0 -> un'altra iterazione ;
; Zero flag = 1 -> esci dal programma ;
;-----------------------------------------------------------------------;
TEST_FINALE PROC NEAR
MOV DX,OFFSET TERMINE ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ;e la stampa.
CALL LETTURA_SN ;Legge da tastiera senza echo.
CMP AL,'n' ;Modifica il FLAG 'Z'
RET ;Ritorno alla procedura chiamante
TEST_FINALE ENDP
;************************************************* ***********************;
;* Procedure di basso livello di interfaccia *;
;************************************************* ***********************;
SPOSTA_CURSORE PROC NEAR
MOV BH,PAGINA ;Pagina video attiva
MOV AH,02h ;Servizio BIOS 'Set Cursor
INT 10h ;Position'
RET
SPOSTA_CURSORE ENDP
;------------------------------------------------------------------------;
; Procedura per leggere da tastiera uno dei tasti 'S' o 'N' ;
; ritorna solo dopo aver letto almeno uno dei due tasti ;
; ;
; REGISTRI UTILIZZATI: AX ;
; CODICI DI RITORNO: in AL il codice ASCII letto ;
;------------------------------------------------------------------------;
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 e' 'N' esce
JZ FINE_LETT ;dalla procedura
CMP AL, 's' ;Se non e' 'S', ne legge
JNZ NUOVA_LETTURA ;un altro
FINE_LETT: RET ;Ritorno alla procedura chiamante
LETTURA_SN ENDP
STAMPA_NUMERO PROC NEAR
ADD AL, '0' ;La base da cui partire e' '0'
MOV AH,W_CHR_TTY ;Servizio BIOS 'write Char in TTY'
INT BIOS_VIDEO
RET ;Ritorno alla procedure chiamante
STAMPA_NUMERO ENDP
STAMPA_STRINGA PROC NEAR
MOV AH,09h ;Servizio DOS 'Print String'; la
INT 21h ;stringa è puntata da DSX.
RET ;ritorno alla procedura chiamante
STAMPA_STRINGA ENDP
CSEG ENDS
END MAIN
Anche guardando il codice vi accorgerete che sono un apprendista dell'assembler e quindi dico a chiunque mi risponda che può fare una grande opera di bene!!!![]()
p.s.: per precisare l'architettura usata è l' 8086.
Grazie in anticipo per le eventuali risposte.