Informática Numaboa - Tutoriais e Programação
Cap. IV - Condições e Loops
Dom 16 Dez 2007 14:03 |
- Detalhes
- Categoria: MASM + RadASM
- Atualização: Quinta, 18 Junho 2009 11:18
- Autor: Alan Moreno
- Acessos: 10192
Masm32+RadASM
Capítulo IV: Condições e Loops
Escrito por: ^A|An M0r3N0^ Conselheiro: RedH@wk Tradução: ~Uglinho~O presente texto foi escrito para fins educacionais e de pesquisa e é de livre distribuição contanto que se preserve o conteúdo e os direitos do autor.
O Masm32 pode utilizar o bloqueio .if (condição) e também .while, .repeat/.until (Loops). Aprenderemos duas formas de utilizá-las. A primeira será utilizando bloqueios, a outra será usando instruções CMP e JXX.
Condições
Usando o bloqueio .IF - O MASM pode fazer comparações simples e complexas de forma fácil. Conheça a sintaxe.
Uma comparação simples seria desta maneira:
Simples | Simples mais .else |
Se desejar fazer comparações sequenciais:
Sequencial | Sequencial mais .else |
Antes de começar com os exercícios, observemos a seguinte tabela de operadores para as comparações:
Operadores de Comparação | |
== | igual |
!= | não igual |
> | maior |
>= | maior ou igual |
< | menor |
<= | menor ou igual |
Operadores de Multi-comparação | |
&& | AND lógico "E" |
|| | OR lógico "OU" |
Operador para verificar o estado das bandeiras (flags) do processador | |
CARRY? | bit do Carry setado |
OVERFLOW? | bit do Overflow setado |
PARITY? | bit da Paridade setado |
SIGN? | bit de Sinal setado |
ZERO? | bit do Zero setado |
No exercício a seguir faremos uma série de comparações. Para isto utilizaremos a biblioteca rvlcnrand.lib para gerar valores inteiros aleatórios. Os algoritmos geradores foram criados por Randall Hyde, desenvolvedor do compilador HLA (High Level Assembly) e passado para o MASM32 por minha pessoa.
Biblioteca rvlcnrand.lib | |
Função | Descrição |
randzime | Com esta função criamos um ponto ao acaso para que possa ser utilizado pelas 4 funções seguintes: random, range, uniform, urange. Desta maneira sempre se poderá gerar de forma aleatória. |
random | Gera números aleatórios uniformemente distribuídos utilizando um algoritmo linear. O resultado é devolvido em EAX. Invoke random |
range | Gera um número aleatório usando a função random,
levando em conta o limite estabelecido. O resultado é devolvido
em EAX. Invoke range, inicio, final |
uniform | Esta função gera um novo número aleatório uniformemente distribuído em cada chamada. O resultado é devolvido em EAX. Invoke uniform |
urange | Gera um número aleatório usando a função urange levando em conta o limite estabelecido. O resultado é devolvido em EAX. Invoke urange, inicio, final |
Exemplo:
Para assistir ao vídeo, faça o download de prog005_ha_c.exe.
Analisando prog005
Como já vimos na ajuda "win32programmer's Reference", a função Messagebox, uma vez executada, devolve para EAX o valor do botão que pressionamos. Para recordar:
O que faz é comparar se pressionamos o botão Yes/Sim e, se esta condição for cumprida, mostrará a mensagem que indicamos.
Analisando o programa prog005a
Este programa é igual ao exercício anterior, só que adicionamos o bloqueio .else para o caso da condição não se cumprir.
Se nossa primeira condição não se cumprir, a outra mensagem que está sob o bloqueio .else será mostrada.
Analisando o programa prog005b
Neste exercício utilizamos o bloqueio .elseif para realizar várias comparações porque a função Messagebox contém 3 botões diferentes e EAX pode ter qualquer um desses 3 valores.
Neste exercício não levamos em consideração o botão Cancel, mas se quiser, você pode adicioná-lo.
Analisando o programa prog005c
Neste exercício utilizamos a biblioteca rvlcnrand.lib para criarmos uma série de comprovações utilizando a maioria de operadores que vimos:
No primeiro bloqueio, .if eax > 10 && eax <=15, se o valor de EAX for maior que 10 e se for menor ou igual a 15, a mensagem será mostrada. Repare que o operador && é um elo para outra comparação e significa "E". Então, para que a mensagem ser mostrada, as duas condições precisam ser cumpridas.
No terceiro bloqueio, .elseif eax == 15 || eax == 16, se o valor de EAX for igual a 15 ou se EAX for igual a 16, a mensagem será mostrada. Também há outro operador elo "||", que significa "OU". Então, para que a mensagem possa ser mostrada, as duas condições precisam ser cumpridas.
Também podemos fazer comparações utilizando instruções:
Destino - podem ser variáveis e registradores de 8, 16, 32 bits. Fonte - podem ser variáveis, registradores e valores inteiros.
Esta instrução compara os dois operandos e, por sua vez, modifica as bandeiras AF, CF, OF, PF, SF, ZF do microprocessador.
Esta instrução salta até um endereço. Vejamos a tabela de alguns saltos e seus significados:
Instrução | Descrição | Estado das bandeiras |
JA | saltar se estiver acima | CF=0 e ZF=0 |
JAE | saltar se estiver acima ou for igual | CF=0 |
JB | saltar se estiver abaixo | CF=1 |
JBE | saltar se estiver abaixo ou for igual | CF=1 ou ZF=1 |
JE | saltar se for igual | ZF=1 |
JG | saltar se for maior | ZF=0 ou SF = OF |
JGE | saltar se for maior ou igual | SF = OF |
JL | saltar se for menor | SF != OF |
JLE | saltar se for menor ou igual | ZF=1 ou SF != OF |
JMP | saltar diretamente | - |
JNA | saltar se não estiver acima | CF=1 ou ZF=1 |
JNAE | saltar se não estiver acima ou for igual | CF=1 |
JNB | saltar se não estiver abaixo | CF=0 |
JNBE | saltar se não estiver abaixo ou for igual | CF=0 e ZF=0 |
JNE | saltar se não for igual | ZF=0 |
JNG | saltar se não for maior | ZF=1 ou SF != OF |
JNGE | saltar se não for maior ou igual | SF != OF |
JNL | saltar se não for menor | SF = OF |
JNLE | saltar se não for menor ou igual | ZF=0 e SF = OF |
Pergunta: Para que serve o estado da bandeira ou Flag? Cada instrução e salto é executada se uma determinada condição for cumprida. Por exemplo:
JA será executado quando a bandeira CF for igual a 0 e ZF também for igual a zero.
JBE será executado quando a bandeira CF for igual a 1 ou ZF for igual a 1.
Reparem que JMP não tem condição. Isto significa que essa instrução não precisa de nenhuma condição para ser executada.
É por isso que a instrução CMP modifica essas bandeiras, é para que o salto colocado na linha seguinte possa ser executado.
Então vamos analisar o prog006, onde encontraremos o seguinte:
Primeiro utilizamos CMP para comparar EAX com a constante IDYES. Se não forem iguais, saltará para a etiqueta Fim; se coincidir, mostrará a mensagem.
Este exercício seria o mesmo que o prog005. A diferença é que não utilizamos o bloqueio .if. Façamos o mesmo com o prog005b usando instruções:
Para fazer comparações com instruções, devemos saber cada significado dos saltos.
Agora utilizaremos as bibliotecas rvlcnrand.lib para gerar um valor aleatório e a biblioteca masm.lib, porque será usada a função dwtoa para mostrar o resultado.
Quando a mensagem será mostrada?
A mensagem será mostrada quando EAX for menor que 5
A mensagem será mostrada quando EAX for maior que 10
O valor será mostrado quando nenhuma condição for cumprida.
Loops
Nos loops estudaremos os bloqueios .while e .repeat/.until para criar laços que se repitam até que a condição que determinamos seja cumprida ou não.
.while
Este bloqueio criará um laço ou loop sempre e enquanto a condição for cumprida. Caso não se cumpra, o laço é interrompido. Sua sintaxe é a seguinte:
Exemplo:
Este laço se repetirá sempre e enquanto eax for maior que 1. Se não for cumprida, o laço se romperá. Se não quisermos fazê-lo com bloqueios, também podemos fazer com instruções puras desta maneira:
Como imitamos o bloqueio .while, criamos um salto diretamente para a instrução cmp. Logo em seguida vem o salto JA (saltar se estiver acima), o que acontece caso eax estiver acima de 1. Este laço se romperá quando eax for 0.
.repeat / .until
Este laço funciona ao contrário de .while. Neste caso o laço terminará quando cumprir a condição e sua sintaxes é assim:
Exemplo:
O laço se repetirá até que eax seja maior que 6. Assim como no bloqueio .while, também podemos obter o mesmo resultado com instruções feitas desta maneira:
Vejamos o seguinte video com exemplos de loops (laços):
Para assistir ao vídeo, faça o download de prog007_ha_b.exe.
Analisando o prog007 - Criando loop com o bloqueio .while:
Esta função busca o título da janela ou também a classe da janela e, se a encontra, devolve o manipulador (handle) da janela para o registro EAX. Para mais informação revisem a documentação Win32 Programmer's Reference Fig. 2.
Linha 9 - Buscamos o título da janela. Se a encontrar, devolverá o manipulador (handle) em EAX.
Linha 10 - Criamos um laço com o bloqueio .while. Se EAX for maior que 1, o laço se realizará sempre e enquanto EAX for maior do que 1. É por isto que foi posta novamente a função Findwindow antes de .endw, na linha 12, para que o laço prossiga até que não encontre o título da janela. Se não o encontrar, EAX será 0 e o laço se romperá.
Analisando o prog007a - Criando laço com o bloqueio .repeat/.until:
Linha 9 - Criamos um ponto ao acaso para que possa criar valores aleatórios com a função range.
Linha 10 - A função range devolve em EAX um valor compreendido entre 0 e 100.
Este laço se repetirá até que o conteúdo de EBX seja maior do que EAX. É por isto que se soma 1 a EBX a partir de 0. Como se sabe, o valor de EAX é desconhecido porque este valor é determinado pela função range.
Com esta função passamos o conteúdo de ebx para o formato ASCII, mas este não é o único formato para o qual podemos passar. Vejamos o seguinte exemplo:
Agora mostraremos 2 valores, em decimal e hexadecimal. Outra coisa importante é que a função wsprintf só tem 2 parâmetros fixos, os outros são opcionais. Só podemos adicioná-los quando queremos passar de um formato para outro como, por exemplo:
- %d para formato decimal
- %x para formato hexadecimal
Nossa cadeia tem 2 formatos:
Por isto é necessário colocar 2 parâmetros a mais na nossa função que, no caso, são eax e ebx. Vejamos como se alinha cada registro com seu formato:
No exemplo a seguir adicionaremos um ícone na nossa aplicação:
Agregando um ícone
Algumas aplicações no nosso PC têm seus próprios ícones. Nós também personalizaremos nosso programa com um ícone próprio. O que devemos fazer é por nosso ícone num recurso e o faremos desta maneira:
Para assistir ao vídeo, faça o download de prog008.exe.
Nota - É importante que o ícone esteja dentro da pasta do nosso projeto.
Adicionando uma ferramenta
Alguma vez você já se perguntou como saber quais funções pertencem a qual biblioteca? Pois ao nosso RADASM adicionaremos um programa para buscar a função e nos mostrar que biblioteca onde se encontra.
Para assistir ao vídeo, faça o download de Add_tools.exe.
Exercícios
- Crie um loop que se repita 1000 vezes com .while e .repeat/.until
- Crie um loop para que mostre uma mensagem 5 vezes.
- Utilizando a função wsprintf e gerando um valor aleatório, crie um programa que mostre uma mensagem com o valor decimal e hexadecimal:
Vocabulário
handle - É o manipulador da janela. Cada janela de nosso sistema tem um handle diferente, é um valor para identificar cada janela.
Lembrando
Não esquecer de perguntar na lista MASM32-RadASM. As soluções destes exercícios serão enviados para a lista dentro de uma semana. Vocês também podem enviar suas prórias soluções.
Se tiverem dúvidas, sugestões ou outros, faça-as na lista de discussão.
O autor pode ser contactado
eMail: O endereço de e-mail address está sendo protegido de spambots. Você precisa ativar o JavaScript enabled para vê-lo. ou O endereço de e-mail address está sendo protegido de spambots. Você precisa ativar o JavaScript enabled para vê-lo.
Lista de discussão MASM32-RadASM
http://groups.google.es/group/MASM32-RadASM
www
Copyright(c) 2005-2006 RVLCN
Recado da vó
Aqui está o código fonte dos exercícios deste tutorial:
- prog005.zip
- prog005a.zip
- prog005b.zip
- prog005c.zip
- prog006.zip
- prog006a.zip
- prog006b.zip
- prog007.zip
- prog007a.zip
- prog007b.zip
- prog008.zip