description |
---|
Registrador EFLAGS e FLAGS. |
O registrador EFLAGS contém flags que servem para indicar três tipos de informações diferentes:
- Status -- Indicam o resultado de uma operação aritmética.
- Control -- Controlam alguma característica de execução do processador.
- System -- Servem para configurar ou indicar alguma característica do hardware relacionado a execução do código ou do sistema.
Enquanto o RFLAGS de 64 bits contém todas as mesmas flags de EFLAGS sem nenhuma nova. Todos os 32 bits mais significativos do RFLAGS estão reservados e sem nenhum uso atualmente. Observe a figura abaixo retirada do Intel Developer's Manual Vol. 1, mostrando uma visão geral do bits de EFLAGS:
Instruções que fazem operações aritméticas modificam as status flags conforme o valor do resultado da operação. São instruções como ADD
, SUB
, MUL
e DIV
por exemplo.
Porém um detalhe que é interessante saber é que existem duas instruções que normalmente são utilizadas para definir essas flags para serem usadas junto com uma instrução condicional. Elas são: CMP
e TEST
. A instrução CMP
nada mais é do que uma instrução que faz a mesma operação aritmética de subtração que SUB
porém sem modificar o valor dos operandos.
Enquanto TEST
faz uma operação bitwise AND (E bit a bit) também sem modificar os operandos. Ou seja, o mesmo que a instrução AND
. Veja a tabela abaixo com todas as status flags:
Bit | Nome | Sigla | Descrição |
---|---|---|---|
0 | Carry Flag | CF | Setado se uma condição de Carry ou Borrow acontecer no bit mais significativo do resultado. Basicamente indica o overflow de um valor não-sinalizado. |
2 | Parity Flag | PF | Setado se o byte menos significativo do resultado conter um número par de bits ligados (1). |
4 | Auxiliary Carry Flag | AF | Setado se uma condição de Carry ou Borrow acontecer no bit 3 do resultado. |
6 | Zero Flag | ZF | Setado se o resultado for zero. |
7 | Sign Flag | SF | Setado para o mesmo valor do bit mais significativo do resultado (MSB). Onde 0 indica um valor positivo e 1 indica um valor negativo. |
11 | Overflow Flag | OF | Setado se o resultado não tiver o sinal esperado da operação aritmética. Basicamente indica o overflow de um número sinalizado. |
{% hint style="info" %} Carry, ou carrinho/transporte, é o que a gente conhece no Brasil como "vai um" em uma operação aritmética de adição. Borrow é o mesmo princípio porém em aritmética de subtração, em linguagem coloquial chamado de "pegar emprestado". {% endhint %}
Dentre essas flags somente CF pode ser modificada diretamente e isso é feito com as seguintes instruções:
stc ; (Set CF) Seta o valor da Carry Flag
clc ; (Clear CF) Zera o valor da Carry Flag
cmc ; (coMplement CF) Inverte o valor da Carry Flag
Bit | Nome | Sigla | Descrição |
---|---|---|---|
10 | Direction Flag | DF | Controla a direção para onde as instruções de string (MOVS , SCAS , STOS , CMPS e LODS ) irão decorrer a memória. |
Se DF estiver setada as instruções de string irão decrementar o valor do(s) registrador(es). Se estiver zerada ela irá incrementar, que é o valor padrão para essa flag.
std ; (Set DF) Seta o valor da Direction Flag
cld ; (Clear DF) Zera o valor da Direction Flag
{% hint style="warning" %} Caso sete o valor dessa flag é importante que a zere novamente em seguida. Código compilado normalmente espera que por padrão essa flag esteja zerada. Comportamentos imprevistos podem acontecer caso você não a zere depois de usar. {% endhint %}
As system flags podem ser lidas por qualquer programa porém somente o sistema operacional pode modificar seus valores (exceto ID). Abaixo irei falar somente das flags que nos interessam saber por agora.
Bit | Nome | Sigla | Descrição |
---|---|---|---|
8 | Trap Flag | TF | Se setada o processador irá executar as instruções do programa passo a passo. Nesse modo o processador dispara uma exception para cada instrução executada. É normalmente usada para depuração de código. |
9 | Interrupt enable Flag | IF | Controla a resposta do processador para interrupções que podem ser ignoradas (interrupções mascaráveis). |
12-13 | I/O Privilege Level field | IOPL | Indica o nível de acesso para a comunicação direta com o hardware (operações de I/O) do programa atual. |
14 | Nested Task flag | NT | Se setada indica que a tarefa atual está vinculada com uma tarefa anterior. Essa flag controla o comportamento da instrução IRET . |
16 | Resume Flag | RF | Se setada as exceptions disparadas pelo processador são temporariamente desabilitadas na instrução seguinte. Geralmente usada por depuradores. |
17 | Virtual-8086 Mode flag | VM | Em protected mode se essa flag for setada o processador entra em modo Virtual-8086. |
21 | Identification flag | ID | Se um processo conseguir setar ou zerar essa flag, isto indica que o processador suporta a instrução CPUID . |
{% hint style="info" %} IOPL na verdade não é uma flag mas sim um campo de 2 bits que indica o nível de privilégio de acesso para operações de I/O a partir da porta física do processador. {% endhint %}
As instruções abaixo podem ser utilizadas para modificar o valor de IF:
sti ; (Set IF) Seta o valor da Interrupt Flag
cli ; (Clear IF) Zera o valor da Interrupt Flag
Em real mode dentre as system flags somente TF e IF existem e não dependem de qualquer tipo de privilégio para serem modificadas, qualquer software executado pelo processador tem permissão irrestrita às flags.