0
Obrigado

Algumas palavras de agradecimento nunca são demais.

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



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. 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!
Este documento, intitulado 'Exercício do Assembly x86 ocorrência de um caractere', está disponível sob a licença Creative Commons. Você pode copiar e/ou modificar o conteúdo desta página com base nas condições estipuladas pela licença. Não se esqueça de creditar o CCM (br.ccm.net) ao utilizar este artigo.

0 Comentário