Riconoscimento cifre, lettere in assembly 16 bit

di Anonimizzato15226 il
18 risposte
Ciao a tutti,
devo creare una funzione che dato in ingresso il codice ASCII di un carattere devo dire se si tratta di una cifra, una lettera o nessuno dei 2. Non devo però usare codici ASCII di limitazione nel codice, e non riesco a capire come fare...
Utilizzo assembly a 16 bit

CPU X64
global findchr

findchr:
push ebp
mov ebp,esp
mov ebx, [ebp+8] ;carico l'argomento
........

pop ebp
ret
Grazie per l'aiuto!!

18 Risposte

  • Che vuol dire "codici ASCII di limitazione"?
  • Mi sono espresso male, nel senso che non devo mettere nel codice i codici ASCII!
  • Ovvero ? Nel codice puoi confrontare con
    '0'
    '9'
    'A'
    'Z'

    o no?
  • Si cosi è possibile!
  • Quindi puoi scrivere il codice ...
  • Se usi l'assembly a 16 bit non dovresti usare i registri classici (bx, bp ecc.) al posto degli extended?

    Comunque, concettualmente non vedo il problema; si tratta di eseguire confronti del tipo '0'<=al<='9', che in assembly si fanno con un codice del tipo:
    
    CMP al, '0'
    JL label2
    CMP al, '9'
    JG label1
    ; dichiaro che si tratta di una cifra
    
    label1: ; faccio la stessa cosa per vedere se è una lettera
    label2: ; se è <'0' o >'z' non è sicuramente né una cifra né una lettera.
    
    ciao
  • Grazie dvaosta!!
    Hai ragione volevo dire 32 ho sbagliato!!
    Allora in pratica la funzione mi deve restituire 1 se è una cifra o una lettera altrimenti 0, ecco il file .asm
    
    CPU X64
    global aisalnum
    aisalnum:
    			push ebp
    			mov ebp, esp
    			mov eax, [ebp+8]
    			
    			cmp al,'0'
    			jl fine
    			cmp al,'9'
    			jle valido
    			cmp al, 'Z'
    			jg fine
    			cmp al,'a'
    			jge valido
    			
    valido:
    			mov BYTE [eax], 1
    			pop ebp
    			ret
    
    fine:
    			mov BYTE [eax], 0
    			pop ebp
    			ret			
    
    e come file .c
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int aisalnum(int a);
    
    int main(int argc, char** argv)
    {
    	int a = 60;
    	int x;
    	
    	x = aisalnum(a);
    	printf("La funzione resituisce il valore : %d\n",x);
    	
    	return 0;
    }
    
    Sono nuovo alla programmazione assembly, secondo voi dove sbaglio??
    Grazie per l'aiuto!
  • Ciao
    scusa se mi intrometto c'è un errore in quanto tra "Z" e "a" ci sono dei codici che devi scartare.
    cosi come tra "9" e "A" come puoi vedere nella classica tabella ascii che puoi trovare al seguente link
    http://www.oppo.it/tabelle/tabella_ascii.ht
  • Si si giusto!!
    la cosa che però non capisco è perché non mi fa eseguire il .exe, si blocca e mi esce dal terminale!
  • Non ti da nessun errore o interviene il debug?
    che compilatore usi?
  • jason ha scritto:


    Grazie dvaosta!!
    Hai ragione volevo dire 32 ho sbagliato!!
    Allora in pratica la funzione mi deve restituire 1 se è una cifra o una lettera altrimenti 0, ecco il file .asm
    
    CPU X64
    global aisalnum
    aisalnum:
    			push ebp
    			mov ebp, esp
    			mov eax, [ebp+8]
    			
    			cmp al,'0'
    			jl fine
    			cmp al,'9'
    			jle valido
    			cmp al, 'Z'
    			jg fine
    			cmp al,'a'
    			jge valido
    			
    valido:
    			mov BYTE [eax], 1
    			pop ebp
    			ret
    
    fine:
    			mov BYTE [eax], 0
    			pop ebp
    			ret			
    
    e come file .c
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int aisalnum(int a);
    
    int main(int argc, char** argv)
    {
    	int a = 60;
    	int x;
    	
    	x = aisalnum(a);
    	printf("La funzione resituisce il valore : %d\n",x);
    	
    	return 0;
    }
    
    Sono nuovo alla programmazione assembly, secondo voi dove sbaglio??
    Grazie per l'aiuto!
    Dubito che sia possibile usare RET per tornare indietro da un salto. Da quel che ne so RET ricarica nell'instruction pointer l'indirizzo di ritorno di una procedura che era stato messo nello stack da CALL; dal momento che i salti non memorizzano da nessuna parte questo indirizzo, mi sa che non funziona e quindi è quello che ti blocca il programma (probabilmente l'assemblatore non controlla questi errori).

    La soluzione è riorganizzare la serie di confronti e salti come ho fatto sopra, in modo da evitare di tornare indietro.

    ciao
  • Allora in c++ devi dichiarare la funzione come esterna
    per par cio' devi inserire dove sono definiti i prototipi di funzione la seguente riga:
    extern "C" int_stdcall aisalnum(int variabile)
    a questo punto se la variabile deve essere modificata la devi passare come puntatore altrimenti va bene cosi come è
    nel file assembler
    .486
        .model flat, stdcall
          option casemap:none
        .code
                  aisalnum proc  Arg1:Dword
             mov eax,Arg1
             cmp al,'0'
             jl fine
             cmp al,'9'
             jle valido
             cmp al, 'Z'
             jg fine
             cmp al,'a'
             jge valido
             ; qui andrebbero inseriti i controlli che ti dicevo prima con la z minuscola e la A maiuscola.
    valido:
            mov eax,1
            jmp short conclusione
    fine:
            mov eax,0
    conclusione:
            ret  4 ; consideri il parametro che è già nello stack
                  aisalnum endp
        end
    in questo caso non c'è bisogno che modifichi il parametro di ingresso perchè per default la convenzione di chiamata stdcall restituisce in eax.
    se usi visual c ti spiego come agganciare la routine al programma.
  • Se stai usando il visual c
    la procedura per agganciare il modulo assembler la trovi al seguente form:
    cplusplus/assembler-t15388.html?hilit=masm#p8488105
    spero di esserti stato d'aiuto
  • Io ho provato cosi ma non mi fa compilare e mi dice:
    nasm: fatal : unable to open input file
    
    CPU X64
     
    global aisalnum 
    
    aisalnum:
              push ebp          
              mov ebp,esp       
              mov ebx,[ebp+8]  
              
    		  cmp ebx,'0'
    		  jl label2
    		  cmp ebx,'9'
    		  jg label1
    		  jmp label4
    		  		  
    label1:
    		cmp ebx,'A'
    		jl label2
    		cmp ebx,'Z'
    		jg label3
    		jmp label4
    		
    label3:	cmp ebx,'a'
    		jl label2
    		cmp ebx,'z'
    		jg label2
    		jmp label4
    		
    label2:
    		mov BYTE [eax],0
    		pop ebp
    		ret
    		  
    label4:
    		mov BYTE [eax],1
    		pop ebp
    		ret
    
    stesso errore anche se metto
    
    label2:
    		mov eax,0
    		pop ebp
    		ret
    		  
    label4:
    		mov eax,1
    		pop ebp
    		ret
Devi accedere o registrarti per scrivere nel forum
18 risposte