Faça uma pergunta »

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

Setembro 2015



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
Para uma leitura offline, é possível baixar gratuitamente este artigo no formato PDF:
Exercicio-do-assembly-x86-ocorrencia-de-um-caractere.pdf

Veja também

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
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 CCM (br.ccm.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.