» Início » Desenvolvimento » Desenvolv de Software » Assembly - O Registrador de Estado - EFLAGS
 
Avaliação: | Publicado em: 12/12/2006
Assembly - O Registrador de Estado - EFLAGS
Adriano Oliveira Técnico em contabilidade, mas nas horas livres estuda programação. Tem conhecimentos de Borland C++ Builder, VisualBasic, HTML, Assembly.


E aí, tudo bem?

Como prometi, vou lhe apresentar um registrador de uso muito especial – o EFLAGS.

Na verdade, esse registrador é uma coleção bem eclética de bits que indicam como está o processador após executar uma instrução.

Com esse registrador, podemos saber se dois valores são iguais, se um é maior que outro, se um valor é negativo, se o resultado de um cálculo ultrapassou os limites suportados por um determinado tipo de dado, se devemos ler/escrever na memória da esquerda para direita, ou na ‘contramão’, à moda dos árabes e judeus, entre outras coisas, bem esquisitas.

Embora seja um registrador de 32 bits, como seus irmãos, na maioria dos casos usaremos apenas seus primeiros bits – e apenas leremos apenas UM bit para então tomarmos alguma decisão.

Veja como está organizado esse registrador:

BIT N.º

B

A

9

8

7

6

5

4

3

2

1

0

 

Nome(ou valor padrão)

OF

DF

IF

TF

SF

ZF

0

AF

0

PF

1

CF

De entre todos esses, usaremos muito os seguintes com muita freqüência em nossa DLL:

  • CF – Carry Flag – indica que, após uma operação, surgiu um valor superior ao tamanho de um dado.

Por exemplo, se estamos trabalhando com um byte e tentamos fazer uma soma, digamos 250 + 7, nosso byte não vai agüentar o resultado – 257 – pois só sabe "contar" até 255(0xFF) e, para refletir isso, o resultado dessa soma será 2 e a Carry Flag será setado, isto é, passará a valer 1, indicando que "subiu um" em nossa soma.

Dessa forma, podemos nos proteger de surpresas desagradáveis fazendo alguma ação dependendo do valor dessa Flag.

  • ZF – Zero Flag – se estiver setada, indica que o resultado de uma operação sobre um registrador ou área de memória é zero.

Por exemplo, podemos usar esse flag para comparar valores, algo como if(a == 30), em linguagem C/C++. A comparação afetaria a Zero Flag mas manteria o valor da variável.

Imagine que o comando "if(a == 30)" pudesse ser reescrito como a = a – 30; if(a = 0)...

Se a variável "a" for realmente igual a 30, depois do cálculo, fazemos alguma coisa, caso contrário... teremos perdido nossa variável...

Mas não se preocupe, ao fazer comparações de valores com os registradores, você nunca perderá seus dados.

  • SF – Signal Flag – se o bit mais significante de um valor(o mais à esquerda) de um resultado for 1, esse flag é setado.

Num valor do tipo byte, essa flag é setada após o valor hexadecimal 0x80, quando o seu oitavo bit é 1.

Esse flag é usado para saber se um valor é positivo(SF =0) ou negativo(SF = 1), se ele for declarado como um número com sinal.

  • OF – Overflow Flag – esse flag indica que houve um estouro no cálculo efetuado entre números com sinal.

Esse flag é usado quando o CF deixa a desejar em cálculos como:

AL = 254(sem sinal) ou –2(com sinal)

AL = 254 + 5 = 259

Nesse caso, o Carry Flag é setado, pois o resultado superou o limite de um byte.

Mas se estamos trabalhando com inteiro sinalizado, -2, em nosso exemplo, o resultado do cálculo seria 3, o que está dentro do limite dos inteiros sinalizados(-127 a +128, para os bytes).

Isso poderia causar problemas em nossos cálculos... imagine se você está fazendo um programa de contabilidade... e um sujeito deve $2,00 e paga com uma nota de $5,00 o resultado poderia levar a uma função de conversão errada, dando o resultado 258, quando, na verdade, o correto seria 3, que seria o valor correto para o troco.

Assim, se o resultado estiver dentro dos limites do inteiro com sinal, o OF será zero, caso contrário, se o valor do cálculo exceder esse limite, o OF será UM.

Mas na maioria das vezes, não precisaremos no preocupar com o valor de cada um desses flags, basta que saibamos como usar as instruções de comparação e de saltos(jumps) condicionais.

Suponha o seguinte trecho de um programa em C/C++ que não faz absolutamente nada de interessante:

...

ax = 0x200;

ax = cx * 0x200;

if

(ax == 0x1000)

ax = 0x3000;

else

ax = 0x2000;

...

Um compilador poderia construir a seguinte versão em Assembly:

...

mov ax, 0x200

mul cx

cmp ax, 0x1000

je _AX_3000

jmp _AX_2000

_AX_3000:

mov ax, 0x3000
jmp _Sai

_AX_2000:
mov ax, 0x2000

_Sai:

...

A instrução cmp faz uma comparação entre dois valores e reflete o resultado no registrador de estado do processador.

Embora conhecer quais flags são afetadas seja muito importante, não precisamos, necessariamente, saber quais foram afetadas, como já disse mais acima.

As instruções de "pulo" vão avaliar essas flags e executar um salto, dependendo do valor da flag.

Veja duas das várias instruções de saltos condicionais que usaremos em nossa DLL:

- JE à Jump if Equal à Pula para um determinado endereço se os dois valores comparados pela instrução "CMP" forem iguais.

- JNE à Jump if Not Equal à Pula se os dois valores forem diferentes.

Essas duas instruções avaliam a Zero Flag. A primeira é executada se ZF = 1 e a outra, se Z = 0.

Veremos mais detalhes sobre isso no decorrer dos artigos.

Vamos parar um pouco por aqui.

No próximo artigo veremos como fazer uma DLL que não faz nada e como usá-la em nossa linguagem de programação preferida.

Espero que tenham gostado dessa teoria toda.

Até mais.


Aguardo a continuação.
Dovanil Jair <dovaniljair@ig.com.br>
Muito bom os teus artigos.
Muito bom está série que vc está nos mostrando!!!
Parabéns!!
Continue...
Paulo
Aguardando continuacao, quem sabe umas video aulas. :-)
felipeq <email>
não existe na internet TUTORIAL MLEHOR QUE ESSE!
FOI O MLEHOR
MEUS PARABENS1!
=)
muito obrigado por voce ter feito esse tutorial,ja faz muito tempo que queria programar uma assembler,mais nao sabia copilar..entao pro favor continua....
esperando continuacao......
Como faço para continuar...a aprender (compilar)
olha vc poderia deixar um aviso do dia que vc vai terminar o tutorial ....e pq ai fica aqui esperando sem saber o dia que vai sair a outra parte e se sair entao por favor nos avise....esperando continuaçao....
Tenho trabalhado com a na minha estação de de programação (Icel MX-909) e tem surgido pequenas dúvidas sobre o funcionamento dos comandos gostaria de obter mais detalhes, continue nos enviando seu material esta sendo de grande ajuda
obrigado
Reginaldo
http://www.icel-manaus.com.br/produtos.asp?idproduto=98
ai o link do Kit educaional
praque quer aliar programação e automação
Estudo VB e estava procurando algo diferente como assembly e achei interessante, sei que não devo me intrometer mas gostaria que postasse um projeto qlqr para download ou apenas os códigos
Espero continuação <hutter@gmail.com>
Muito bom , espero uma continuação