Junte-se
à comunidade
Inscreva-se
Faça uma pergunta »

Exercício do Assembly x86 ocorrência de um caractere

Maio 2013



Introdução


Este pequeno exercício de linguagem de montagem x86 visa às arquiteturas x86 (Processadores Intel e AMD de 32 bits) e utiliza a sintaxe Nasm, um "assembly" livre, gratuito e irrestrito em diversas plataformas como Windows ou Linux.
Da mesma forma as funções externas são utilizados a partir da biblioteca C padrão.
Então, você não terá problemas com a sua máquina para fazer este exercício: ele não depende do sistema operacional utilizado. Ele só dependente da arquitetura x86.
NOTA: Para usar o Nasm, a fim de testar esse exercício, você encontrará um tutorial para usar/instalar o Nasm no Windows e no Linux, clicando aqui.

Noções abordadas neste exercício

  • Escrita de uma função com gestão dos parâmetros de entrada
  • Gestão de tabelas

Enunciado


Imaginemos uma tabela de caracteres (que não se termina, obrigatoriamente, com 0). Temos o seu tamanho e queremos testar a presença de um determinado caractere nesta tabela. O objectivo será o de entrar uma função que toma como entrada uma tabela de caracteres, seu tamanho e um caractere. Se este caractere estiver presente na tabela, retornaremos um valor diferente de zero, caso contrário, retornaremos a zero.

Veja o que dará esta função em C:
//O protótipo desta função 
int está_na_tabela(char *tabela int tamanho, char c);  
//Exemplo de uso: 
char tab[] = {'n', 'e', 'u', 'e'}; 
está_na_tabela(tab, sizeof(tab), 'u'); //Retornará outra coisa além do 0 
está_na_tabela(tab, sizeof(tab), 'a'); // Retornará 0 


Você deverá inserir este código:
extern printf 

section .data 
 tabela db 'dadedidadedavivoufufifamasibifisaz' 
 sim db 'sim', 10, 0 
 não db 'não', 10, 0 

section .text 
 global main 

está_na_tabela: 
 ;Insira seu código aqui! 


main: 
 push ebp 
 mov ebp, esp 
  
       ;Vamos testar se m está presente na tabela 
 push dword 'm' 
 ;O comprimento da tabela (aqui 34)  
 push dword 34  
 ;Endereço da cadeia no eax 
 push tabela 

        ;Apelo de está_na_tabela com o endereço da tabela,  
        ;seu tamanho, e o valor a ser procurado 
 call está_na_tabela
 teste eax, eax 
 jnz está_presente ;Se eax != 0 então exibimos sim 
 push não ;Se não exibiremos não 
 jmp exibir 
        ;Exibir a cadeia com printf 
   está_presente: 
 push sim 
   exibir: 
 call printf 

 mov eax, 0 
 leave 
 ret


Vamos lá! Pense um pouco, se necessário. Faça uma pesquisa sobre as instruções em relação às cadeias. Não há indícios para este exercício!

Correção


Veja uma solução:
está_na_tabela: 
 ;Recuperamos o endereço da tabela (primeiro parâmetro) em edi 
 mov edi, [esp + 4]  
 ; Recuperamos o tamanho da tabela (segundo parâmetro) em ecx 
 mov ecx, [esp + 8] 
 ;Recuperamos o caractere a ser encontrado (terceiro parâmetro) em eax 
 mov eax, [esp + 12] 

 ;Busca do caractere 
 repne scasb 
 ;Se o flag ZERO (ZF) está em 1 é que encontramos o caractere 
 ;Se não é que não o encontramos 
 ;Então basta entrar o valor de ZF em eax 
 mov eax, 0 
 ;Si ZF = 1 então al = 1 (al sendo 8 bits inferior a eax) 
 setz al  

 ret

Explicação


O objetivo é o de você utilizar a combinação das instruções do tipo "rep" et "scas". Aqui nós usamos "repne" . Esta instrução repete a instrução que a segue decrementando ecx a cada repetição. Este circuito termina quando ecx = 0, ou quando o flag Zero (ZF) é a 1. A instrução scasb, entretanto, busca a presença de um caractere (alojado em al, parte inferior do eax) no local da memória apontada pelo edi. Se al é igual ao valor apontado pelo edi, então o flag zero é definido como 1. Então, em todos os casos, o edi é incrementado por 1.

Veja o que acontece, já que, na verdade, o que acaba de ser explicado não é muito convincente:

ZF = 0 
ecx = comprimento 
eax = caractere 
edi = tabela 
//Circuito que representa o "repne scasb" 
Quando ecx != 0 ET ZF = 0 Fazer 
    Si al == [edi] Então 
        ZF = 1 
    FinSi 
    ecx = ecx - 1 
    edi = edi + 1 
Fim EnquantoQue 

eax = 0 
//Condição que representa o "setz" 
Si ZF = 1 Então 
    eax = 1 
FinSi


Pronto!


Tradução feita por Lucia Maurity y Nouira

A ver igualmente

Comunidade de assistência e de conselho.

Ejercicio de ensamblador x86: ocurrencia de un carácter
Ejercicio de ensamblador x86: ocurrencia de un carácter
Por Carlos-vialfa em 7 de outubro de 2009
Exercice assembleur x86 occurence d'un caractère
Exercice assembleur x86 occurence d'un caractère
Por kilian em 10 de abril de 2008
Artigo original publicado por kilian. Tradução feita por pintuda.
Este documento, intitulado « Exercício do Assembly x86 ocorrência de um caractere »a partir de Kioskea (pt.kioskea.net) está disponibilizado sob a licença Creative Commons. Você pode copiar, modificar cópias desta página, nas condições estipuladas pela licença, como esta nota aparece claramente.
Receber a nossa newsletter

Compilar um programa de linguagem de montagem com o Nasm
Exercício de Assembly (linguagem de montagem) x86 número primo