[ASSEMBLY X86-C]

di il
6 risposte

[ASSEMBLY X86-C]

Buonasera a tutti.
Dunque in questo esercizio devo implementare 2 funzioni in assembly da chiamare da C:
La funzione aisalnum prende in ingresso il codice ASCII di un carattere e mette in (E)AX, prima di terminare, il valore 1 se il carattere in ingresso è una cifra o una lettera oppure 0 se così non è.
La funzione astripnoalnum prende in ingresso un stringa terminata da 0 e la modifica eliminando tutti i caratteri che non sono cifre o lettere. Prima di terminare la funzione mette in (E)AX l'indirizzo della stringa ricevuta.
Questo è il mio codice. La aisalnum funziona, ma la successiva no.
In effetti nella astripnoalnum io chiamo la aisalnum per controllare se il carattere sia una cifra/lettera o meno, e forse è qui che sbaglio.
Vi ringrazio molto. Ancor più se potete darmi delucidazioni e consigli, perchè io per eliminare i caratteri ho preferito crearmi un'altra stringa e poi ricopiarla a partire dal vecchio indirizzo, ma ci sono altri metodi che magari sono anche più facili da implementare. Grazie
section .data
array	times	101	DB	0	; inizializzo array di 101 zeri
section .text

global aisalnum
global astripnoalnum

aisalnum:
		push ebp
		mov ebp, esp
		
		mov eax, [ebp+8]	; inserisco il codice ASCII ricevuto in eax
		cmp eax, '0'
		jb  ritorna0		; se l'ascii code è < di '0' allora non è sicuramente
							; nè una lettera nè una cifra
		cmp eax, '9'
		jbe ritorna1		; altrimenti se non è minore di '0' ma è minore di '9'
							; sarà una cifra e ritorno 1
		cmp eax, 'A'
		jb  ritorna0		; altrimenti se non è una cifra ed è < 'A' allora non
							; è nemmeno una lettera e ritorno 0
		cmp eax, 'Z'
		jbe ritorna1

		cmp eax, 'a'
		jb	ritorna0
		
		cmp eax, 'z'
		jbe ritorna1
		
		; altrimenti ritorna 0
		
ritorna0:
		mov eax, 0
		pop ebp
		ret
		
		
ritorna1:
		mov eax, 1
		pop ebp
		ret
		
		
astripnoalnum:
		push ebp
		mov ebp, esp
		
		mov esi, [ebp+8]	; metto l'indirizzo della stringa nel reg esi
		xor ecx, ecx		; ecx = 0
check:
		cmp DWORD[esi], 0	; se sono a fine stringa esco
		jz  ritorna
		push DWORD[esi]	; controllo se il carattere è una lettera o una cifra
		call aisalnum
		add esp, 4		; tolgo il parametro dallo stack
		
		; aisalnum mi dovrebbe modificare il valore in eax ma forse non lo fa
		
		cmp eax, 1		; se eax e' 1(risultato della chiamata ad aisalnum)
		je  scrivi		; allora copio il carattere nell'array perchè
						; è una cifra o una lettera
		
		; altrimenti...non copio il carattere nell'array
		inc esi
		jmp check
		
		
		
		
scrivi:
		mov eax, [esi]	; lo scrivo nel mio array
		mov [array+ecx], eax
		inc ecx
		inc esi
		jmp check
		
ritorna:
		mov edi, [ebp+8]	; metto l'indirizzo della stringa ricevuta come destinazione
							; copio l'array dove punta edi
		xor edx, edx		; edx = 0
		cld
	lp:						; il valore di ecx maturato finora lo sfrutto per
		mov eax, [array+edx]; produrre questo ciclo
		stosb
		inc edx
		loop lp
		
		mov BYTE [edi], 0	; aggiungo il carattere di fine stringa
		
		mov eax, [ebp+8]	; valore di ritorno è l'indirizzo della stringa di partenza
		pop ebp
		ret
		
		

6 Risposte

  • Re: [ASSEMBLY X86-C]

    Ciao
    allora per evitare di effettuare la copia della stringa basta che inizialmente esi ed edi puntino allo stesso indirizzo.
    quando devi scrivere sulla stringa dopo aver scritto incrementi edi e il gioco è fatto.
    ricordati però alla fine di mettere 0 o null come terminatore della stringa.

    un altro consiglio ti conviene inizialmente calcolare la dimensione della stringa cosi da poter utilizzare una istruzione loop invece della jmp
    cio ti permetterebbe di evitare anche lo scarico su un buffer ausiliario che poi dovrebbe essere ricopiato tecnica che ti ho spiegato prima.

    quale è il problema la funzione va in loop o altro?
    fammi sapere cosi ti do una mano

    spero di esserti stato d'aiuto.
  • Re: [ASSEMBLY X86-C]

    Grazie! Il problema è che quando chiamo la funzione aisalnum a partire dalla astripnoalnum non mi viene aggiornato il valore di ritorno della aisalnum che dovrebbe essere salvato in eax(0 o 1), ma risulta essere sempre 0 e quindi la mia funzione non copia alcun carattere dato che l'istruzione
    cmp eax, 1
    risulta essere sempre falsa
  • Re: [ASSEMBLY X86-C]

    Hai provato la funzione da sola ?
    comunque l'exit point deve essere unico
    modifica il codice
    ritorna0:xor eax,eax
    jmp fine_routine
    ritorna1: mov eax,1
    fine_routine:
                       pop ebp
                       ret
    vediamo con queste modifiche cosa succede
  • Re: [ASSEMBLY X86-C]

    Si funziona perchè la chiamo prima da codice c e parte. Poi sempre da C chiamo la funzione astripnoalnum che a sua volta fa uso della aaisalnum per verificare che il carattere della stringa sia una lettera o una cifra
  • Re: [ASSEMBLY X86-C]

    Scusa il ritardo per la risposta
    nel tuo codice ho trovato un grave errore
    la MOV [array+ecx],eax ; significa il dato della locazione di memoria indirizzata da array+ecx=eax
    esempio locazione 100+1=00000041 = 'A' il che non centra niente con il tuo array
    ma nelle specifica devi modificare l'array cosa che non avviene.
    l'istruzione corretta sarebbe MOV array[ecx],eax indirizzamento di un array. Ma anche questa istruzione non è corretta perchè dalle specifiche si lavora con i caratteri che sono dei byte mentre questa istruzione lavora sulle DWORD.
    quindi andresti a modificare 4 caratteri alla volta creando un papocchio!
    la soluzione è MOV byte ptr array[ecx],al
    perchè al è un registro a 8 bit quindi gestisce i byte
    e cosi puoi modificare un carattere alla volta.
    non preoccuparti del caricamento nel registro al perchè viene fattoautomaticamente quando esegue la Mov eax,[esi]

    un altro errore che c'è e il seguente
    check:
    cmp DWORD[ESI],0
    anche qui lavori con dimensioni sbagliate
    l'istruzione giusta è CMP byte ptr [esi],0

    un consiglio non usare ecx ,registro contatore, per indirizzare i vettori perchè ad esso sono legate diverse istruzioni che involotareamente possono darti problemi di difficile rilevazione.
    usa ebx,registro base, che è stato "creato" appositamente per gli indirizzamenti.

    fammi sapere se ci sono altri errori
  • Re: [ASSEMBLY X86-C]

    Le Push Dword vanno bene perche lo stack lavora a 32 bit qundi con le Dword.
Devi accedere o registrarti per scrivere nel forum
6 risposte