# 2. Estruturas condicionais

## Introdução

O **Assembly** é uma linguagem de programação de baixo nível que representa instruções de máquina executadas diretamente pelo processador, específica para arquiteturas como x86, MIPS ou ARM. Esta documentação cobre os fundamentos do Assembly, com ênfase em **estruturas condicionais** e outras estruturas de controle (como laços e tratamento de erros), incluindo uma comparação com linguagens como Python e Bash.

## Estrutura Básica de um Programa Assembly

Um programa Assembly é um arquivo de texto (extensão `.asm` ou `.s`) com instruções traduzidas por um assembler (e.g., NASM para x86, mips-as para MIPS) em código de máquina. Abaixo, um exemplo em x86-64 com uma condicional:

```nasm
section .data
    numero dd 18         ; Inteiro de 32 bits
    msg_maior db 'Maior ou igual a 18', 0xa
    len_maior equ $ - msg_maior
    msg_menor db 'Menor que 18', 0xa
    len_menor equ $ - msg_menor

section .text
    global _start

_start:
    mov eax, [numero]    ; Carrega numero
    cmp eax, 18          ; Compara com 18
    jge maior            ; Salta se maior ou igual
    mov rsi, msg_menor   ; Mensagem para menor
    mov rdx, len_menor
    jmp exibir
maior:
    mov rsi, msg_maior   ; Mensagem para maior
    mov rdx, len_maior
exibir:
    mov rax, 1           ; Syscall para escrever
    mov rdi, 1           ; stdout
    syscall
    mov rax, 60          ; Syscall para sair
    xor rdi, rdi         ; Código de saída 0
    syscall
```

* `section .data`: Define dados inicializados.
* `section .text`: Contém o código executável.
* `;`: Inicia um comentário.
* Instruções como `cmp`, `jge`: Implementam condicionais.

## Instruções Básicas

### Operações com Registradores

| Instrução | Descrição   | Exemplo (x86)  | Exemplo (MIPS)      |
| --------- | ----------- | -------------- | ------------------- |
| `MOV`     | Copia dados | `mov rax, 42`  | `li $t0, 42`        |
| `ADD`     | Soma        | `add rax, rbx` | `add $t0, $t1, $t2` |
| `SUB`     | Subtrai     | `sub rax, 5`   | `sub $t0, $t1, 5`   |

### Manipulação de Memória

| Arquitetura | Leitura          | Escrita          |
| ----------- | ---------------- | ---------------- |
| x86-64      | `mov eax, [rbx]` | `mov [rbx], eax` |
| MIPS        | `lw $t0, 0($t1)` | `sw $t0, 0($t1)` |

### Controle de Fluxo

| Instrução (x86) | Instrução (MIPS)     | Descrição                 |
| --------------- | -------------------- | ------------------------- |
| `JMP label`     | `j label`            | Salto incondicional       |
| `CMP a, b`      | `slt` / `slti`       | Compara valores           |
| `JE label`      | `beq rs, rt, label`  | Salta se igual            |
| `JNE label`     | `bne rs, rt, label`  | Salta se diferente        |
| `JG label`      | `bgt rs, rt, label`  | Salta se maior (signed)   |
| `JL label`      | `blt rs, rt, label`  | Salta se menor (signed)   |
| `JA label`      | `bgtu rs, rt, label` | Salta se maior (unsigned) |
| `JB label`      | `bltu rs, rt, label` | Salta se menor (unsigned) |
| `CALL label`    | `jal label`          | Chama função              |
| `RET`           | `jr $ra`             | Retorna de função         |

### Operações Lógicas

| Instrução | Descrição     | Exemplo (x86)  | Exemplo (MIPS)        |
| --------- | ------------- | -------------- | --------------------- |
| `AND`     | AND bit a bit | `and rax, rbx` | `and $t0, $t1, $t2`   |
| `OR`      | OR bit a bit  | `or rax, 0xFF` | `or $t0, $t1, 0xFF`   |
| `XOR`     | XOR bit a bit | `xor rax, rax` | `xor $t0, $t0, $t0`   |
| `NOT`     | NOT bit a bit | `not rax`      | `nor $t0, $t1, $zero` |

## Estruturas Condicionais e de Controle no Assembly

### Estrutura Condicional (If-Else)

#### Assembly (x86)

Usa `CMP` para comparar e saltos condicionais como `JGE`, `JE`, `JL`:

```nasm
    mov eax, [numero]
    cmp eax, 18
    jge maior           ; Salta se >= 18
    ; Código para menor
    mov rsi, msg_menor
    mov rdx, len_menor
    jmp exibir
maior:
    ; Código para maior/igual
    mov rsi, msg_maior
    mov rdx, len_maior
exibir:
    ; Código comum
    mov rax, 1
    mov rdi, 1
    syscall
```

#### Assembly (MIPS)

Usa `slt` para comparação e `beq`/`bne` para saltos:

```nasm
    lw $t0, numero
    li $t1, 18
    slt $t2, $t0, $t1   ; $t2 = 1 se $t0 < $t1
    beq $t2, $zero, maior ; Se $t0 >= 18, salta
    ; Código para menor
    la $a0, msg_menor
    j exibir
maior:
    ; Código para maior/igual
    la $a0, msg_maior
exibir:
    li $v0, 4           ; syscall print_string
    syscall
```

#### Comparação com Outras Linguagens

**Python:**

```python
numero = 18
if numero >= 18:
    print("Maior ou igual a 18")
else:
    print("Menor que 18")
```

* Sintaxe clara, alto nível, sem gerenciamento manual.

**Bash:**

```bash
numero=18
if [ "$numero" -ge 18 ]; then
    echo "Maior ou igual a 18"
else
    echo "Menor que 18"
fi
```

* Focado em scripts, usa operadores como `-ge`, mais abstrato que Assembly.

**Características do Assembly:**

* Exige comparações explícitas e saltos.
* Depende de flags (x86) ou registradores (MIPS).
* Mais verboso, mas altamente eficiente.

***

### Laço (For)

#### Assembly (x86)

Usa um contador e salto condicional:

```nasm
    mov ecx, 5          ; Contador (5 iterações)
loop_start:
    ; Código a ser repetido
    dec ecx             ; Decrementa contador
    jnz loop_start      ; Salta se não zero
```

**Com contador crescente:**

```nasm
    mov ecx, 0          ; Contador inicial
loop_start:
    cmp ecx, 5          ; Compara com limite
    jge loop_end        ; Sai se >= 5
    ; Código a ser repetido
    inc ecx             ; Incrementa contador
    jmp loop_start
loop_end:
```

#### Assembly (MIPS)

```nasm
    li $t0, 5           ; Contador (5 iterações)
loop_start:
    ; Código a ser repetido
    addiu $t0, $t0, -1  ; Decrementa
    bnez $t0, loop_start ; Salta se não zero
```

**Com contador crescente:**

```nasm
    li $t0, 0           ; Contador inicial
loop_start:
    li $t1, 5           ; Limite
    bge $t0, $t1, loop_end ; Sai se >= 5
    ; Código a ser repetido
    addiu $t0, $t0, 1   ; Incrementa
    j loop_start
loop_end:
```

#### Comparação com Outras Linguagens

**Python:**

```python
for i in range(5):
    print(i)
```

* Abstrai o contador e a condição, fácil de usar.

**Bash:**

```bash
for i in {1..5}; do
    echo $i
done
```

* Ideal para scripts, sintaxe simplificada.

**Características do Assembly:**

* Gerenciamento manual do contador e condição.
* Usa registradores para controle.
* Flexível, mas propenso a erros.

***

### Laço (While)

#### Assembly (x86)

Verifica a condição no início:

```nasm
    mov eax, [valor]
while_start:
    cmp eax, 10
    jge while_end       ; Sai se >= 10
    ; Código a ser repetido
    inc eax
    mov [valor], eax
    jmp while_start
while_end:
```

#### Assembly (MIPS)

```nasm
    lw $t0, valor
while_start:
    li $t1, 10
    bge $t0, $t1, while_end  ; Sai se >= 10
    ; Código a ser repetido
    addiu $t0, $t0, 1
    sw $t0, valor
    j while_start
while_end:
```

#### Do-While (executa pelo menos uma vez)

**x86:**

```nasm
    mov eax, [valor]
do_while:
    ; Código a ser repetido
    inc eax
    cmp eax, 10
    jl do_while         ; Continua se < 10
```

**MIPS:**

```nasm
    lw $t0, valor
do_while:
    ; Código a ser repetido
    addiu $t0, $t0, 1
    li $t1, 10
    blt $t0, $t1, do_while  ; Continua se < 10
```

#### Comparação com Outras Linguagens

**Python:**

```python
valor = 5
while valor < 10:
    valor += 1
```

* Condição explícita, sem gerenciamento de registradores.

**Bash:**

```bash
valor=5
while [ $valor -lt 10 ]; do
    valor=$((valor + 1))
done
```

* Usa sintaxe de teste `[ ]`, voltado para automação.

**Características do Assembly:**

* Condição implementada com comparação e salto.
* Requer gerenciamento manual de registradores/memória.
* Mais controle, mas mais complexo.

***

### Switch-Case

#### Assembly (x86)

Usa comparações encadeadas ou tabela de saltos:

```nasm
    mov eax, [opcao]
    cmp eax, 1
    je case_1
    cmp eax, 2
    je case_2
    cmp eax, 3
    je case_3
    jmp default_case

case_1:
    ; Código para opção 1
    jmp end_switch
case_2:
    ; Código para opção 2
    jmp end_switch
case_3:
    ; Código para opção 3
    jmp end_switch
default_case:
    ; Código padrão
end_switch:
```

**Tabela de saltos (mais eficiente para muitos casos):**

```nasm
section .data
    jump_table dq case_1, case_2, case_3
    default_case dq default_handler

section .text
    mov eax, [opcao]
    cmp eax, 3
    ja default_case
    dec eax                     ; Índice base 0
    mov rbx, [jump_table + rax*8]
    jmp rbx
```

#### Assembly (MIPS)

```nasm
    lw $t0, opcao
    li $t1, 1
    beq $t0, $t1, case_1
    li $t1, 2
    beq $t0, $t1, case_2
    li $t1, 3
    beq $t0, $t1, case_3
    j default_case

case_1:
    ; Código para opção 1
    j end_switch
case_2:
    ; Código para opção 2
    j end_switch
case_3:
    ; Código para opção 3
    j end_switch
default_case:
    ; Código padrão
end_switch:
```

***

### Tratamento de Erros (Try-Except)

Assembly não possui um mecanismo nativo de `try-except` como linguagens de alto nível. Tratamento de erros é feito verificando condições específicas ou usando interrupções/exceções do sistema operacional.

#### Verificando Códigos de Erro (x86)

```nasm
    ; Tenta abrir arquivo
    mov rax, 2          ; sys_open
    mov rdi, filename
    mov rsi, 0          ; O_RDONLY
    syscall

    cmp rax, 0
    js erro             ; Salta se negativo (erro)

    ; Sucesso - rax contém file descriptor
    mov [fd], rax
    jmp continua

erro:
    ; Tratamento de erro
    mov rsi, msg_erro
    mov rdx, len_erro
    mov rax, 1
    mov rdi, 2          ; stderr
    syscall

    ; Sai com erro
    mov rax, 60
    mov rdi, 1
    syscall

continua:
    ; Continua execução normal
```

#### Tratamento de Overflow em MIPS

```nasm
    lw $t0, valor1
    lw $t1, valor2
    addu $t2, $t0, $t1      ; Soma sem sinal

    ; Verifica overflow (se resultado < qualquer operando)
    blt $t2, $t0, overflow
    blt $t2, $t1, overflow
    j no_overflow

overflow:
    ; Tratamento de overflow
    la $a0, msg_overflow
    li $v0, 4
    syscall
    li $v0, 10
    syscall

no_overflow:
    ; Continua execução
```

#### Comparação com Outras Linguagens

**Python:**

```python
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Erro de divisão por zero")
```

* Abstrai o tratamento de erros, fácil de usar.

**Bash:**

```bash
if ! command; then
    echo "Comando falhou"
fi
```

* Tratamento básico via códigos de saída (`$?`), menos robusto.

**Características do Assembly:**

* Sem `try-except` nativo; erros são gerenciados manualmente.
* Depende de códigos de retorno ou interrupções.
* Exige conhecimento profundo do sistema operacional e hardware.

## Flags e Seus Usos (x86)

O processador x86 mantém um registrador de flags que é afetado por instruções como `CMP`, `TEST`, `ADD`, etc.

| Flag | Nome     | Quando é setada                        |
| ---- | -------- | -------------------------------------- |
| ZF   | Zero     | Resultado igual a zero                 |
| SF   | Sign     | Resultado negativo (bit mais alto = 1) |
| OF   | Overflow | Overflow em operação com sinal         |
| CF   | Carry    | Carry em operação sem sinal            |

### Exemplos de Uso

```nasm
; Verificar se é zero
cmp rax, 0
je zero            ; ZF = 1

; Verificar sinal
cmp rax, rbx
jl negativo        ; SF != OF (para signed)

; Verificar carry (unsigned)
cmp rax, rbx
jb abaixo          ; CF = 1
ja acima           ; CF = 0 e ZF = 0
```

### Instrução TEST

`TEST` faz AND bit a bit sem modificar operandos, apenas flags:

```nasm
test rax, rax      ; Verifica se rax é zero
jz is_zero         ; Se ZF = 1

test rax, 1        ; Verifica se é ímpar
jnz is_odd         ; Se bit 0 = 1
```

## Boas Práticas com Estruturas de Controle

* **Rótulos descritivos**: Use nomes como `loop_start`, `maior`, `erro_abrir` para clareza.
* **Minimize saltos**: Reduza ramificações para melhor legibilidade.
* **Teste condições**: Cubra todos os casos possíveis em condicionais.
* **Gerencie registradores**: Evite sobrescrever valores críticos em loops.
* **Use `test` para zero**: Mais eficiente que `cmp reg, 0`.
* **Prefira loops descendentes**: `dec` + `jnz` é mais eficiente.

## Permissões e Execução

```bash
# Compilar (x86-64)
nasm -f elf64 programa.asm -o programa.o

# Linkar
ld programa.o -o programa

# Executar
./programa

# Compilar com debug symbols
nasm -f elf64 -g programa.asm -o programa.o
ld programa.o -o programa
gdb ./programa
```

## Comparação Resumida

| Estrutura      | Assembly (x86/MIPS)                 | Python               | Bash                           |
| -------------- | ----------------------------------- | -------------------- | ------------------------------ |
| **If-Else**    | `CMP`, `JGE`, `BEQ`, saltos manuais | `if exp: else:`      | `if [ cond ]; then ... fi`     |
| **For**        | Contador manual, `CMP`, `JNZ`       | `for i in range(n):` | `for i in {1..n}; do ... done` |
| **While**      | Condição com `CMP`, `JGE`, `SLT`    | `while exp:`         | `while [ cond ]; do ... done`  |
| **Switch**     | Comparações encadeadas ou tabela    | `match/case` (3.10+) | `case`                         |
| **Try-Except** | Verificação manual, saltos          | `try: except:`       | `if ! cmd; then ... fi`        |

## Importância

Estruturas condicionais e de controle em Assembly são cruciais para lógica em sistemas embarcados, drivers e engenharia reversa. Sua eficiência e proximidade com o hardware permitem otimização, mas exigem precisão na implementação.

## Boas Práticas Gerais

* Comente cada bloco para explicar a lógica.
* Use depuradores (GDB, PEDA) para testar fluxos.
* Consulte manuais da arquitetura (e.g., Intel para x86).
* Estruture o código para facilitar manutenção.
* Teste com diferentes entradas e casos limite.

## Recursos Adicionais

* **Livro Gratuito**: [Aprendendo Assembly](https://mentebinaria.gitbook.io/assembly) (x86/x86-64)
* **Manuais Intel**: [Volume 2A](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html)
* **Ferramentas**: NASM ([nasm.us](https://nasm.us/)), PEDA ([github.com/longld/peda](https://github.com/longld/peda)), mips-gcc
* **Documentação MIPS**: Capítulo 11 (PDF fornecido)

## Exemplo Completo: Calculadora Simples

```nasm
; calculadora.asm - Calculadora com switch-case
section .data
    msg_menu db 'Escolha:', 0xa
             db '1 - Soma', 0xa
             db '2 - Subtracao', 0xa
             db '3 - Multiplicacao', 0xa
             db '4 - Divisao', 0xa
             db 'Opcao: ', 0
    msg_num1 db 'Digite o primeiro numero: ', 0
    msg_num2 db 'Digite o segundo numero: ', 0
    msg_result db 'Resultado: ', 0
    msg_erro db 'Erro: Divisao por zero!', 0xa, 0
    msg_invalido db 'Opcao invalida!', 0xa, 0
    fmt_int db '%d', 0
    fmt_result db '%d', 0xa, 0

section .bss
    opcao resd 1
    num1 resd 1
    num2 resd 1
    result resd 1

section .text
    global _start
    extern printf, scanf

_start:
    ; Exibe menu
    mov rdi, msg_menu
    call printf

    ; Lê opção
    mov rdi, fmt_int
    mov rsi, opcao
    call scanf

    ; Lê primeiro número
    mov rdi, msg_num1
    call printf
    mov rdi, fmt_int
    mov rsi, num1
    call scanf

    ; Lê segundo número
    mov rdi, msg_num2
    call printf
    mov rdi, fmt_int
    mov rsi, num2
    call scanf

    ; Switch-case
    mov eax, [opcao]
    cmp eax, 1
    je .soma
    cmp eax, 2
    je .subtracao
    cmp eax, 3
    je .multiplicacao
    cmp eax, 4
    je .divisao
    jmp .invalido

.soma:
    mov eax, [num1]
    add eax, [num2]
    mov [result], eax
    jmp .exibir

.subtracao:
    mov eax, [num1]
    sub eax, [num2]
    mov [result], eax
    jmp .exibir

.multiplicacao:
    mov eax, [num1]
    imul eax, [num2]
    mov [result], eax
    jmp .exibir

.divisao:
    mov eax, [num2]
    cmp eax, 0
    je .erro_divisao
    mov eax, [num1]
    cdq
    idiv dword [num2]
    mov [result], eax
    jmp .exibir

.erro_divisao:
    mov rdi, msg_erro
    call printf
    jmp .fim

.invalido:
    mov rdi, msg_invalido
    call printf
    jmp .fim

.exibir:
    mov rdi, msg_result
    call printf
    mov rdi, fmt_result
    mov esi, [result]
    call printf

.fim:
    mov rax, 60
    xor rdi, rdi
    syscall
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/conceitos/programacao-e-linguagens/assembly/2.-estruturas-condicionais.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
