View Full Version : [Assembly] Stampare Stringa Alla Rovescio
dengel_1
27-02-2007, 20:22
Ho un problema..il programma stampa oltre alla stringa ribaltata anche
faccine varie . E ed U..ovvero codice ascii casuali..come posso risolvere?
vi posto il codice..:mad:
.MODEL TINY
.CODE
ORG 0100h
START: jmp MAIN
STRINGA db 5,0,0,0,0,0,0
;----------------------------------------------------------------------------
MAIN PROC
;input stringa
mov ah,0ah
lea dx,STRINGA
int 21h
;stampa stringa
lea bx, STRINGA
inc bx
mov cx,0
mov cl,[bx]
inc bx
mov ah,2; stampa
;stampa stringa al contrario
Ribaltamento:
mov ch,0
lbl_a: mov cl,[bx]
mov dl,[bx]
inc bx
loop lbl_a
mov ch,0
mov cl,dl
lbl_r: mov dl,[bx]
mov ah,2
int 21h
dec bx
loop lbl_r
lbl_s: mov dl,[bx]
mov ah,2
int 21h
dec bx
loop lbl_s
int 20h
MAIN ENDP
;----------------------------------------------------------------------------
END START
END
non ho provato il code ma prova a dichiarare la stringa così:
STRINGA DB "mia stringa",'$'
probabilmente ti stampa segno strani, cuoricini e faccine perchè hai messo lo 0 finale alla stringa con il tasm devi limitarla con il '$' finale.
prova a dichiarare la stringa così:
STRINGA DB "mia stringa",'$'Lui non deve mettere una stringa "literal", in quanto usa il servizio 0Ah/int 21h che effettua l'input di una stringa. Il buffer deve essere impostato con 2 byte di "header" come spiegato <qui> (http://www.ctyme.com/intr/rb-2563.htm).
probabilmente ti stampa segno strani, cuoricini e faccine perchè hai messo lo 0 finale alla stringa con il tasm devi limitarla con il '$' finale.Il tasm non c'entra nulla. Il '$' va usato come terminatore di una stringa solo quando si usa il servizio 09h/int 21h (che lui non ha usato).
Ho un problema..il programma stampa oltre alla stringa ribaltata anche
faccine varie . E ed U..ovvero codice ascii casuali..come posso risolvere?Il sorgente è un po' confuso ... ci sono istruzioni a mio avviso inutili.
Se vuoi stampare una stringa rovesciata, hai 2 possibilità: rovesciare fisicamente la stringa nel buffer e quindi stamparla, oppure stampare semplicemente i caratteri partendo dall'ultimo verso il primo.
Se non ci sono richieste/necessità particolari, consiglierei il secondo modo. Una volta che in CX hai la lunghezza della stringa e BX punta al byte che contiene la lunghezza, basta sommare CX a BX, quindi finché CX è diverso da 0 stampare il carattere in [BX] e decrementare BX e CX.
Verrebbe circa la metà di quanto hai scritto ...
EDIT: Invece di usare BX e CX si potrebbe usare SI come base e BX come offset, usando il modo di indirizzamento [BX+SI]. Sarebbe ancora meglio!!
dengel_1
28-02-2007, 12:44
BX punta al byte che contiene la lunghezza,
Come faccio a puntare bx al byte contenente la lunghezza?
per sommare poi
JZ lbl_somma
lbl_somma: ADD bx,cx
DEC cx
DEC bx
Ho cercato di tradurre in codice quello che mi hai detto..ora ci vorrebbe un tuo aiuto nel collegare tutto quanto :)
Ho cercato di tradurre in codice quello che mi hai detto..ora ci vorrebbe un tuo aiuto nel collegare tutto quanto :)Guarda ... è abbastanza semplice. Nel tuo codice hai usato BX che punta inizialmente al primo byte del buffer e CX come contatore (la parte bassa la prendi dal secondo byte del buffer).
Nell'EDIT ho detto che si può usare l'indirizzamento . In effetti non mi è venuto in mente subito ma consentirebbe di eliminare alcune istruzioni.
In sostanza usi SI per puntare al buffer e il contatore dei caratteri lo metti in BX. Cambia poco dal tuo, solo i registri.
Poi però se SI lo lasci che punta al secondo byte (quello della lunghezza restituita), facendo [BX+SI] prendi il carattere dall'ultimo fino al primo.
Ad ogni ciclo verifichi [B]prima che BX sia uguale a zero e se lo è esci dal ciclo. Altrimenti prendi il carattere con [BX+SI], lo stampi e quindi decrementi BX e ripeti il ciclo.
dengel_1
28-02-2007, 14:37
Siccome a scuola non abbiamo mai usato si, è meglio utlizzare i reigstir utilizzati fino ad ora..visto che è un esercitazione da consegnare :)
Non potendo usare si, devo utilizzare esclusivamente i registri
cx,bx,dx e ax..
Nel mio caso Bx= primo byte
Ma non capisco come fare a dirgli..Leggi a partire dall' ultimo byte di bx( senza usare si ovviamente)..grazie x la disponibilità :)
Ma non capisco come fare a dirgli..Leggi a partire dall' ultimo byte di bx( senza usare si ovviamente)..grazie x la disponibilità :)Uh ... ok, allora non usiamo SI. ;)
Se in CX hai il numero di caratteri e BX sta puntando al secondo byte del buffer, basta che sommi CX a BX. Poi nel loop dovrai decrementare sia BX che CX.
dengel_1
28-02-2007, 18:00
Ribaltamento:
add cx,bx
jz
lbl_b: dec bx
dec cx
loop
mov cx,[bx]
mov ah,2
E ora nel codice? come fare a mettere in pratica quello che hai detto tu? :muro:
mi consigliate una guida per super principianti per l'assembly? si intende x86, e che sia possibilmente aggiornata e gratis
Ribaltamento:
add cx,bx
jz
lbl_b: dec bx
dec cx
loop
mov cx,[bx]
mov ah,2
E ora nel codice? come fare a mettere in pratica quello che hai detto tu? :muro:No no .. alt. Intanto ho detto di sommare CX a BX, non il contrario. Poi nel loop innanzitutto bisogna controllare che CX sia diverso da zero (lo puoi fare con una CMP o anche con una OR su sé stesso). Se è zero, esci dal ciclo. Poi metti in DL il carattere (cioè [BX]), chiami il servizio 02H/int 21H, quindi decrementi BX e CX e ripeti da capo.
allora ecco:
SEG_A SEGMENT
ASSUME CS:SEG_A, DS:SEG_A
ORG 100H
Ribalta PROC FAR
inizio: jmp START ;salta a START
max_len EQU 1000 ;massima lunghezza
sorgente db max_len dup(?) ;stringa da ribaltare
destinaz db max_len dup(?) ;stringa ribaltata
START:
mov si,OFFSET sorgente
prossimo_car: mov ah,01h ;legge un car dalla tastiera
int 21h
cmp al,0Dh ;è = a return ?
je fine_lettura ;se si smetti di leggere
mov sorgente[si],al ;sposta il carattere in sorgente
inc si ;incrementa si
jmp prossimo_car ;leggi il prossimo car
fine_lettura:
mov cx,si
push cx ;memorizza la lunghezza nello stack
mov bx,OFFSET sorgente
mov si,OFFSET destinaz
add si,cx ;metto in si la lunghezza della stringa
dec si ;decrementa si
Ribaltamento:
mov al,[bx] ;routine di ribaltamento
mov [si],al ; parto dal fondo e la copio
inc bx ; in destinaz
dec si
loop Ribaltamento ; salto a Ribaltamento
pop si ;prelevo la lunghezza
mov destinaz[si+1],'$' ;aggiungo il terminatore
mov ah,09h
mov dx,OFFSET destinaz
int 21h ;stampo la stringa ribaltata
RETN
Ribalta ENDP
SEG_A ENDS
END inizio
dengel_1
01-03-2007, 13:18
Quello che mi hai postato utilizza si..e cmq l'avevo già trovato..non fa al caso mio..
Ok il programma stampa la stringa rovesciata ma con 3 faccine(che progresso :D ) Come mai?
;Ribaltamento
add bx,cx
lbl_b: cmp cx,0
je lbl_fine
mov dl,[bx]
dec bx
dec cx
int 21h
loop lbl_b
lbl_fine:
int 20h
Ok il programma stampa la stringa rovesciata ma con 3 faccine(che progresso :D ) Come mai?metti un jmp lbl_b invece di loop.
Si potrebbe anche benissimo usare l'istruzione loop ma a quel punto dovresti: a) togliere dec cx (lo fa già loop) e b) la comparazione di cx con 0 la puoi fare solo una volta fuori dal ciclo.
mi consigliate una guida per super principianti per l'assembly? si intende x86, e che sia possibilmente aggiornata e gratis
http://xoomer.virgilio.it/ramsoft/
dengel_1
01-03-2007, 18:33
Ho provato a mettere il jmp ma purtoppo se inserisco 123 mi stampa 323 e il programma termina..ci siamo quasi?:rolleyes:
dengel_1
02-03-2007, 18:35
non funge :mad:
non funge :mad:Riposta il codice completo che vediamo.
dengel_1
02-03-2007, 19:49
; Assemblaggio come .COM:
; TASM [nomefile.ASM]
; TLINK [nomefile.OBJ] /t
;---------------------------------------------------------------------------
.MODEL TINY
.CODE
ORG 0100h
START: jmp MAIN
STRINGA db 5,0,0,0,0,0,0
;----------------------------------------------------------------------------
MAIN PROC
;input stringa
mov ah,0ah
lea dx,STRINGA
int 21h
;stampa stringa
lea bx, STRINGA
inc bx
mov cx,0
mov cl,[bx]
inc bx
mov ah,2; stampa
;stampa stringa al contrario
Ribaltamento:
add bx,cx
lbl_b: cmp cx,0
je lbl_fine
mov dl,[bx]
dec bx
dec cx
int 21h
jmp lbl_b
lbl_fine:
int 20h
MAIN ENDP
;----------------------------------------------------------------------------
END START
END
lea bx, STRINGA
inc bx
mov cx,0
mov cl,
[B]inc bxQuest'ultima inc bx non ci deve essere. L'avevo anche detto ... "Se in CX hai il numero di caratteri e BX sta puntando al secondo byte del buffer..."
dengel_1
02-03-2007, 20:22
Si vede che sei un programmatore esperto :D
Ora funziona... grazie :D
dengel_1
02-03-2007, 20:30
Pero' ho un altro problema..
All'inizio del prog ho inserito dei messaggi obbligatori da scivere
MSG1INPUT db "MIONOME",0
MSG2INPUT db 0Dh,0Ah, "E03",0
MSG3INPUT db 0Dh,0Ah,"ROVESCIATO",0
MSG4INPUT db 0dh,0ah,"INSERIRE STRINGA",0
MSG5INPUT db 0dh,0ah,"ROVESCIATA",0
e per richiamare il primo all'inizio dopo il main scrivo
lea bx,MSG1INPUT
Eppure lui lo ignora richiamando l'input..come mai?
Pero' ho un altro problema..
All'inizio del prog ho inserito dei messaggi obbligatori da scivere
MSG1INPUT db "MIONOME",0
MSG2INPUT db 0Dh,0Ah, "E03",0
MSG3INPUT db 0Dh,0Ah,"ROVESCIATO",0
MSG4INPUT db 0dh,0ah,"INSERIRE STRINGA",0
MSG5INPUT db 0dh,0ah,"ROVESCIATA",0
e per richiamare il primo all'inizio dopo il main scrivo
lea bx,MSG1INPUT
Eppure lui lo ignora richiamando l'input..come mai?Se vuoi stampare una stringa puoi usare il servizio Int 21H/AH=09H.
MOV AH,09H
MOV DX,OFFSET stringa
INT 21HE nota bene che la stringa deve terminare con un '$' (codice 36)
dengel_1
03-03-2007, 14:40
SI grazie ho risolto..ciao :D :D :D :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.