PDA

View Full Version : Assembler: stringhe


kerikay
04-07-2006, 11:53
Ciao a tutti!
Volevo chiedere se c'è qualcuno che può darmi una mano con Assembler....
Devo fare un programma che riceva in input una stringa (caratteri alfanumerici) e li controlli uno per uno (controllare se sono caratteri alfanumerici, se le lettere sono in maiuscolo,che il totale sia 16,....) mi potetre dare qualche indicazione? :confused:

andbin
04-07-2006, 12:23
Ciao a tutti!
Volevo chiedere se c'è qualcuno che può darmi una mano con Assembler....
Devo fare un programma che riceva in input una stringa (caratteri alfanumerici) e li controlli uno per uno (controllare se sono caratteri alfanumerici, se le lettere sono in maiuscolo,che il totale sia 16,....) mi potetre dare qualche indicazione? :confused:Intanto, giusto per sapere:
- Assembly 80x86?
- In DOS o Windows?
- Con un assembler tipo MASM/NASM, ecc... o assembly "in-line" in "C"?
- Per "riceva in input" vuoi dire da tastiera?

kerikay
04-07-2006, 18:10
si scusami....avrei dovuto già specificare....

Assembly 80x86
in DOS
Assembler tipo TASM
si l'input deve essere da tastiera....

wingman87
04-07-2006, 18:29
Cos'è che non ti è chiaro?

kerikay
04-07-2006, 18:58
non mi è chiaro come gestire le stringhe e fare operazioni con esse
cioè io devo prendere da input di tastiera una serie di lettere e numeri
e controllare se il numero totale dei caratteri è 16
verificare che le lettere siano tutte maiuscole
o tutte consonanti
operazioni di questo genere

repne scasb
04-07-2006, 22:03
Per iniziare la routine che interpreta la pressione di un tasto da tastiera ritornando "scan code" e "carattere":


; Assemby x86/16
;
; Input
; None
; Output
; AH = Scancode
; AL = Carattere

Get_Key proc near

pusha
mov ah,10h
int 16h
push bp
mov bp,sp
mov word ptr [bp+10h],ax
pop bp
popa
ret

Get_Key endp


Devi quindi controllare che il carattere letto in AL sia maiuscolo ossia compreso tra 65 e 90, se inoltre vuoi controllare che sia un numero il valore letto in AL deve essere compreso tra 48 e 57. Riassumendo se vuoi verificare che il carattere letto da tastiera sia alfabetico e maiuscolo o numerico avrai un codice di questo genere:


cmp al,48d
jb carattere_non_valido
cmp al,57d
jb carattere_numerico
cmp al,65d
jb carattere_non_valido
cmp al,90b
jb carattere_alfabetico_maiuscolo


Tutto a meno di errori grossolani.

wingman87
05-07-2006, 10:13
; Assemby x86/16
;
; Input
; None
; Output
; AH = Scancode
; AL = Carattere

Get_Key proc near

pusha
mov ah,10h
int 16h
push bp
mov bp,sp
mov word ptr ,ax
pop bp
[b]popa
ret

Get_Key endp

Ciao, a cosa servono le cose che ho evidenziato in neretto? Il pusha e popa le immagino ma vorrei essere sicuro..

andbin
05-07-2006, 11:09
Ciao, a cosa servono le cose che ho evidenziato in neretto? Il pusha e popa le immagino ma vorrei essere sicuro..NEAR e FAR si usano con le direttive PROC, EXTRN e LABEL. NEAR significa che l'oggetto è nello stesso segmento del programma principale, FAR indica che l'oggetto è in un altro segmento. Spero di averlo spiegato giusto ... non mi ricordo perfettamente. :p

PUSHA / POPA servono per fare il push / pop sullo stack di tutti i registri "general purpose", cioè AX, CX, DX, BX, SP (originale), BP, SI e DI (nell'ordine indicato).

wingman87
05-07-2006, 11:27
PUSHA / POPA servono per fare il push / pop sullo stack di tutti i registri "general purpose", cioè AX, CX, DX, BX, SP (originale), BP, SI e DI (nell'ordine indicato).
Che figo! Xk il nostro prof non ce l'ha spiegato? E' comodissimo! Grazie!

kerikay
05-07-2006, 11:34
grazie delle risposte mi sono molto utili!!!

Ma come faccio a contare i tasti premuti e verificare che siano 16?

repne scasb
05-07-2006, 11:50
grazie delle risposte mi sono molto utili!!!

Ma come faccio a contare i tasti premuti e verificare che siano 16?

Legge 16 caratteri dalla tastiera, controlla che siano numerici o alfabetici e maiuscoli e li pone in un buffer.



MAX_KEY_LEN EQU 16d

data segment byte 'DATA'

key_buffer:
DB MAX_KEY_LEN DUP (?)

data ends

.286
.ALPHA

code segment para use16 'CODE'
assume cs:code

Init proc near

cld
push data
pop ds
push ds
pop es
mov di,OFFSET key_buffer
loop_get_key:
call Get_Key
cmp al,48d
jb no_valid_char
cmp al,57d
jbe valid_input_char
cmp al,65d
jb no_valid_char
cmp al,90d
jbe valid_input_char
jmp no_valid_char
valid_input_char:
stosb
no_valid_char:
cmp di,OFFSET key_buffer+MAX_KEY_LEN
jne loop_get_key
int 20h

Init endp

Get_Key proc near

pusha
mov ah,10h
int 16h
mov bp,sp
mov word ptr [bp+0Eh],ax
popa
ret

Get_Key endp

code ends
end init

repne scasb
05-07-2006, 12:03
PUSHA / POPA servono per fare il push / pop sullo stack di tutti i registri "general purpose", cioè AX, CX, DX, BX, SP (originale), BP, SI e DI (nell'ordine indicato).

L'ordine e' il seguente: DI, SI, BP, SP, BX, DX, CX, AX dalla cima alla coda.

andbin
05-07-2006, 12:45
L'ordine e' il seguente: DI, SI, BP, SP, BX, DX, CX, AX dalla cima alla coda.La sequenza che ho indicato io è quella di push ... per il pop è ovviamente al contrario. ;)

kerikay
05-07-2006, 12:49
però il mio problema è un altro....nel mio codice ho preso da input di tastiera un numero qualsiasi di caratteri....e la lunghezza l'ho salvata in un buffer....
ma io il controllo di questa lunghezza devo farla dopo l'input e stampare a video un messaggio sulla correttezza o meno dell'input....
il mio problema è cm leggere questo buffer.....
mi dispiace di non essere stata chiara.... :(

il mio codice è questo:


DOS EQU 21h
R_KEY_CHR EQU 01h

INVIO EQU 13

CODICE_TASTO DB ?
SEQUENZA DB ?
DIMENSIONE DW ?


LETTURA PROC NEAR
MOV BX,0
CICLO: CALL LETTURA_DATI
CMP AL,INVIO
JZ FINELETTURA
MOV [SEQUENZA+BX],AL
INC BX
JNZ CICLO
FINELETTURA: MOV DIMENSIONE,BX
RET
LETTURA ENDP



LETTURA_DATI PROC NEAR
MOV AH,R_KEY_CHR
INT DOS
MOV [CODICE_TASTO],AL
RET
LETTURA_DATI ENDP

repne scasb
05-07-2006, 18:49
La sequenza che ho indicato io è quella di push ... per il pop è ovviamente al contrario.

Ok. Basta intendersi. In sostanza se lo stack vale 0FFFEh, dopo un pusha avremo:

0FFEEh = DI
0FFF0h = SI
0FFF2h = BP
0FFF4h = SP
0FFF6h = BX
0FFF8h = DX
0FFFAh = CX
0FFFCh = AX

repne scasb
05-07-2006, 19:04
però il mio problema è un altro....[CUT]

Vari errori:

1) Nella routine "LETTURA_DATI" non ti curi di salvaguardare il registro BX utilizzato nel loop "CICLO", la chiamata all'INT 21h puo' sovrascrivere il registro BX.

2) L'istruzione "MOV [SEQUENZA+BX],AL" genera una sovrascrittura di dati, in quanto per "SEQUENZA" viene allocato un unico byte, mentre nella successiva istruzioni incrementi BX.

3) BX viene contemplato per 65535 caratteri con possibilita' di sovrascrivere involontariamente varie aree ("JNZ CICLO") come DTA, stack, data segment...

4) Se si inseriscono 65.536 caratteri il valore della variabile "DIMENSIONE" assumenra' il valore 0 (zero).

5) La varibile "CODICE_TASTO" e' sovrabbondante (non necessaria).

kerikay
05-07-2006, 21:49
quindi dovrei...
1. salvare BX (come?)
2. mettere una dimensione max per sequenza in modo da non cadere in overflow
3.cancello codice tasto

e per quanto riguarda il contare i 16 caratteri?

repne scasb
05-07-2006, 22:41
quindi dovrei...
1. salvare BX (come?)
2. mettere una dimensione max per sequenza in modo da non cadere in overflow
3.cancello codice tasto

e per quanto riguarda il contare i 16 caratteri?

Nel "tuo" modo di scrivere in assembly:


DOS EQU 21h
R_KEY_CHR EQU 01h

INVIO EQU 13

;CODICE_TASTO DB ? ; Non serve
SEQUENZA DB 16d DUP (?) ; Allocazione di 16 bytes
DIMENSIONE DW ?


LETTURA PROC NEAR
MOV BX,0
CICLO: CALL LETTURA_DATI
CMP AL,INVIO
JZ FINELETTURA

; Qui va il codice per
; testare numeri e maiuscole

MOV [SEQUENZA+BX],AL
INC BX
CMP BX,16d ; Controlla che la stringa
JB CICLO ; non sia maggiore di 16 byte
FINELETTURA: MOV DIMENSIONE,BX
RET
LETTURA ENDP



LETTURA_DATI PROC NEAR
PUSH BX ; Salva BX
MOV AH,R_KEY_CHR
INT DOS
;MOV [CODICE_TASTO],AL ; Non serve
POP BX ; Ripristina BX
RET
LETTURA_DATI ENDP

Fenomeno85
05-07-2006, 23:00
repne ma dove hai studiato? :ave:

~§~ Sempre E Solo Lei ~§~

kerikay
19-07-2006, 15:04
razie mlle repne scasb...
una domanda:

la variabile sequenza che ho creato si può considerare un vettore e vi si può accedere ai suoi elementi quando + mi è comodo?

grazie