# Instruções condicionais

As instruções condicionais basicamente avaliam as *status flags* para executar uma operação apenas se a condição for atendida. Existem condições que testam o valor de mais de uma *flag* em combinação para casos diferentes.

A nomenclatura de escrita de uma instrução condicional é o seu nome seguido de um 'cc' que é sigla para *conditional code*. Abaixo uma tabela de códigos condicionais válidos para as instruções `CMOVcc`, `SETcc` e `Jcc`:

{% hint style="info" %}
Os termos "abaixo" (*below*) e "acima" (*above*) usados na descrição se referem a verificação de um valor numérico não-sinalizado. Enquanto "maior" e "menor" é usado para se referir a um valor numérico sinalizado.
{% endhint %}

<table data-header-hidden><thead><tr><th width="150">cc</th><th>Descrição (inglês | português)</th><th>Condição</th></tr></thead><tbody><tr><td>cc</td><td>Descrição (inglês | português)</td><td>Condição</td></tr><tr><td>A</td><td>if Above | se acima</td><td>CF=0 e ZF=0</td></tr><tr><td>AE</td><td>if Above or Equal | se acima ou igual</td><td>CF=0</td></tr><tr><td>B</td><td>if Below | se abaixo</td><td>CF=1</td></tr><tr><td>BE</td><td>if Below or Equal | se acima ou igual</td><td>CF=1 ou ZF=1</td></tr><tr><td>C</td><td>if Carry | se carry flag estiver setada</td><td>CF=1</td></tr><tr><td>E</td><td>if Equal | se igual</td><td>ZF=1</td></tr><tr><td>G</td><td>if Greater | se maior</td><td>ZF=0 e SF=OF</td></tr><tr><td>GE</td><td>if Greater or Equal | se maior ou igual</td><td>SF=OF</td></tr><tr><td>L</td><td>if Less | se menor</td><td>SF!=OF</td></tr><tr><td>LE</td><td>if Less or Equal | se menor ou igual</td><td>ZF=1 ou SF!=OF</td></tr><tr><td>NA</td><td>if Not Above | se não acima</td><td>CF=1 ou ZF=1</td></tr><tr><td>NAE</td><td>if Not Above or Equal | se não acima ou igual</td><td>CF=1</td></tr><tr><td>NB</td><td>if Not Below | se não abaixo</td><td>CF=0</td></tr><tr><td>NBE</td><td>if Not Below or Equal | se não abaixou ou igual</td><td>CF=0 e ZF=0</td></tr><tr><td>NC</td><td>if Not Carry | se carry flag não estiver setada</td><td>CF=0</td></tr><tr><td>NE</td><td>if Not Equal | se não igual</td><td>ZF=0</td></tr><tr><td>NG</td><td>if Not Greater | se não maior</td><td>ZF=1 ou SF!=OF</td></tr><tr><td>NGE</td><td>if Not Greater or Equal |se não maior ou igual</td><td>SF!=OF</td></tr><tr><td>NL</td><td>if Not Less | se não menor</td><td>SF=OF</td></tr><tr><td>NLE</td><td>if Not Less or Equal | se não menor ou igual</td><td>ZF=0 e SF=OF</td></tr><tr><td>NO</td><td>if Not Overflow | se não setado overflow flag</td><td>OF=0</td></tr><tr><td>NP</td><td>if Not Parity | se não setado parity flag</td><td>PF=0</td></tr><tr><td>NS</td><td>if Not Sign | se não setado sign flag</td><td>SF=0</td></tr><tr><td>NZ</td><td>if Not Zero | se não setado zero flag</td><td>ZF=0</td></tr><tr><td>O</td><td>if Overflow | se setado overflow flag</td><td>OF=1</td></tr><tr><td>P</td><td>if Parity | se setado parity flag</td><td>PF=1</td></tr><tr><td>PE</td><td>if Parity Even | se parity indica par</td><td>PF=1</td></tr><tr><td>PO</td><td>if Parity Odd | se parity indicar ímpar</td><td>PF=0</td></tr><tr><td>S</td><td>if Sign | se setado sign flag</td><td>SF=1</td></tr><tr><td>Z</td><td>if Zero | se setado zero flag</td><td>ZF=1</td></tr></tbody></table>

Exemplo:

```nasm
cmp rax, rbx
jnz nao_igual  ; Salta se RAX e RBX não forem iguais
```

Repare como alguns **cc** têm a mesma condição, como é o caso de NE e NZ. Portanto `JNE` e `JNZ` são exatamente a mesma instrução no código de máquina, somente mudando no Assembly.

### JCXZ e JECXZ

Além das condições acima existem mais três `Jcc` que testam o valor do registrador CX, ECX e RCX respectivamente.

| Jcc   | Descrição (inglês \| português)                     | Condição |
| ----- | --------------------------------------------------- | -------- |
| JCXZ  | Jump if CX is zero \| pula se CX for igual a zero   | CX=0     |
| JECXZ | Jump if ECX is zero \|pula se ECX for igual a zero  | ECX=0    |
| JRCXZ | Jump if RCX is zero \| pula se RCX for igual a zero | RCX=0    |

A última instrução, obviamente, somente existe em submodo de 64-bit. Enquanto `JCXZ` não existe em 64-bit.

No código de máquina o opcode dessa instrução é **0xE3** e a alternância entre o tamanho do registrador é feita de acordo com o atributo *address-size*, sendo modificado pelo prefixo **0x67**.
