A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

Flags e saltos condicionais

Sab

20

Jun

2009


19:05

(7 votos, média 5.00 de 5) 


Nível Intermediário A tradução literal de "flag" é bandeira. Não foi por acaso que as "flags" do processador receberam este nome: funcionam como sinalizadores. Vou manter o nome flag e não usar algum tipo de tradução por que esta denominação já foi incorporada ao "computês" do Brasil e não vale a pena discutir ou mudar um hábito. Neste tutorial, aprenda a usar as flags para criar saltos condicionais.

As flags são apenas um único bit de memória localizado dentro do processador. Como cada flag é apenas um bit, num dado momento elas só podem ter o valor 1 ou 0 (flag "setada" ou "zerada"). Existem flags que podem ser usadas para indicar o resultado de certas instruções. Algumas instruções como CMP, TEST e BT não fazem outra coisa a não ser alterar algumas destas flags, outras realizam tarefas adicionais além de alterar algumas das flags. Também existem instruções que simplesmente não alteram as flags.

Um uso comum das flags é o de desviar a execução para um ponto em particular do código usando instruções de salto condicinal. Estas instruções farão o salto (ou não) dependendo do estado de uma ou de mais flags. Apenas cinco das flags podem ser usadas deste modo - as flags zero, sinal, carry, overflow e paridade. A sexta flag (carry auxiliar) e a sétima (flag de direção) são lidas por outro tipo de instrução. A seguir estão informações adicionais a respeito das cinco flags que podem ser usadas por saltos condicionais.

Z (flag zero)

Está setada (tem o valor 1) se o resultado de uma operação for zero. Depois de uma instrução aritmética, se o número deixado no registrador ou na a área de memória objeto da instrução for zero, então a flag é setada. Para obter esta informação geralmente só é preciso fazer uma simples comparação de dois valores sem alterá-los. Neste caso, pode-se usar a instrução CMP. CMP imita um SUB sem alterar os valores passados como operandos. Por exemplo:

CMP EAX,33h ; flag zero = 1 se eax = 33h, mas não altera eax SUB EAX,33h ; flag zero = 1 se eax = 33h (eax diminui em 33h) CMP EAX,EDX ; flag zero = 1 se eax = edx CMP EAX,[VALOR] ; flag zero = 1 se eax = o número em VALOR

A flag zero também pode ser usada para mostrar o resultado de uma contagem crescente ou decrescente, por exemplo:

DEC EAX ; flag zero = 1 se eax for zero depois da instrução. ; flag zero = 0 se eax for diferente de zero. INC EAX ; flag zero = 1 se eax for zero depois da instrução. ; flag zero = 0 se eax for diferente de zero.

A flag zero também pode ser usada para controlar a repetição de instruções de string, isto é, LODS, STOS e MOVS:

CMP EAX,0 ; ver se o número em eax é zero ; (flag zero está setada) OR EAX,EAX ; faz a mesma coisa mas usa 2 opcodes ao invés de 3 TEST EAX,EAX ; faz a mesma coisa e também só usa 2 opcodes

As versões de 16 e 8 bits das instruções testam apenas os primeiros 16 ou 8 bits do registrador ou da área de memória. Por exemplo:

CMP W[JOAO],0 ; ver se os primeiros 16 bits da memória marcada ; como JOAO são zero CMP B[MARIA],0 ; ver se os primeiros 8 bits da memória marcada ; como MARIA são zero OR DX,DX ; ver se o registrador dx é zero (16 bits) TEST DH,DH ; ver se o registrador dh é zero (8 bits) SUB B[VALOR],2 ; reduz os 8 bits guardados em VALOR em 2 ; (flag zero setada se for zero) DEC SI ; flag zero setada quando si for zero (16 bits) INC B[CONTA] ; flag zero setada quando os 8 bits de CONTA são zero

Já que as flags são muito úteis para indicar se houve retorno com sucesso ou não de uma rotina, algumas vezes será preciso setá-las diretamente. Para setar a flag zero pode-se usar:

CMP EAX,EAX ; seta a flag zero sem alterar eax SUB EAX,EAX ; seta a flag zero fazendo eax = 0 CMP EAX,EDX ; quando precisam ser diferentes, zera a flag zero OR EAX,EAX ; quando eax não pode ser zero, zera a flag zero TEST EAX,EAX ; mesmo efeito que OR EAX,EAX

Quando usada com TEST, a flag zero será setada se o bit testado for zero.

MOV ECX,1 ; põe valor 1 em ecx TEST ECX,1 ; a flag zero não é setada CMP ECX,1 ; a flag zero é setada MOV EDX,0 TEST EDX,1 ; a flag zero é setada CMP EDX,1 ; a flag zero não é setada MOV EBX,-1 TEST EBX,-1 ; testa todos os 32 bits (flag zero zerada) CMP EBX,-1 ; ver se ebx é -1 (flag zero setada)

A flag zero é usada principalmente com as instruções de salto condicional JZ (saltar se for zero) e JNZ (saltar se não for zero) , por exemplo:

JZ >L10 ; salta para frente para L10 se flag zero = 1 JNZ L1 ; salta para trás para L1 se flag zero = 0

A flag zero também é utilizada com as instruções de salto condicional JA ("jump if above" - salte se acima), JB ("jump if below" - salte se abaixo) e instruções semelhantes.

Também pode ser usada em um loop utilizando instruções especiais ou apenas a flag, por exemplo:

L1: ... ; outro código aqui CMP EDX,EAX LOOPZ L1 ; decrementa ecx, loop continua até que ecx = 0 ; ou até que edx = eax (quando flag zero = 1) L1: ... ; outro código aqui CMP EDX,EAX LOOPNZ L1 ; decrementa ecx, loop continua até que ecx = 0 ; ou até que edx seja diferente de eax (quando flag zero = 0) L1: ... ; outro código aqui CMP EDX,EAX JZ >L10 ; salte para fora do loop quando edx = eax (flag zero = 1) LOOP L1 ; decrementa ecx, loop continua até que ecx = 0 L10: L1: ... ; outro código aqui CMP EDX,EAX JNZ L1 ; loop continua até que edx = eax (flag zero = 1)

Informações adicionais