# 3. Funcoes & Objetos & Arrays

## Introdução

O **Assembly** é uma linguagem de programação de baixo nível que traduz instruções de máquina diretamente executáveis pelo processador, específica para arquiteturas como x86, MIPS ou ARM. Esta documentação cobre os fundamentos do Assembly, com ênfase em **funções**, **estruturas de dados** (structs) e **arrays**, detalhando sua implementação, características, boas práticas e uma comparação detalhada com linguagens de alto nível como **Python**, **Bash** e **C**.

## 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 função:

```nasm
section .data
    msg db 'Resultado: ', 0
    len equ $ - msg

section .text
    global _start

_start:
    mov rdi, 5        ; Argumento
    call quadrado     ; Chama função
    mov rsi, rax      ; Resultado
    call print_num    ; Exibe (simplificado)
    mov rax, 60       ; Syscall sair
    xor rdi, rdi
    syscall

quadrado:
    mov rax, rdi      ; Copia argumento
    mul rdi           ; rax = rdi * rdi
    ret               ; Retorna
```

* `section .data`: Define dados inicializados.
* `section .text`: Contém o código executável.
* `;`: Inicia um comentário.

## 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`   |
| `MUL`     | Multiplica  | `mul rbx`      | `mul $t0, $t1, $t2` |
| `DIV`     | Divide      | `div rcx`      | `div $t0, $t1`      |

### 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         |
| --------------- | ------------------------------ | ----------------- |
| `CALL label`    | `jal label`                    | Chama função      |
| `RET`           | `jr $ra`                       | Retorna de função |
| `PUSH`          | `addiu $sp, -4`                | Empilha na pilha  |
| `POP`           | `lw $t0, 0($sp); addiu $sp, 4` | Desempilha        |

***

## Funções no Assembly

### Definição e Implementação

Funções em Assembly são blocos de código reutilizáveis, chamadas via `CALL` (x86) ou `JAL` (MIPS) e retornadas com `RET` (x86) ou `JR $ra` (MIPS). Elas seguem **convenções de chamada** (ABI) para gerenciar argumentos e retorno.

### Convenção de Chamada x86-64 (System V AMD64)

| Aspecto                        | Regra                                         |
| ------------------------------ | --------------------------------------------- |
| **Argumentos**                 | RDI, RSI, RDX, RCX, R8, R9 (até 6 argumentos) |
| **Retorno**                    | RAX (inteiro), RDX:RAX (128 bits)             |
| **Registradores caller-saved** | RAX, RCX, RDX, RSI, RDI, R8-R11               |
| **Registradores callee-saved** | RBX, RBP, R12-R15                             |
| **Pilha**                      | Alinhada a 16 bytes antes de CALL             |

#### Exemplo Completo (x86-64)

```nasm
; funcoes.asm - Exemplo de funções com convenção de chamada
section .text
    global _start

; Função soma(a, b) - retorna a + b
; Parâmetros: RDI = a, RSI = b
; Retorno: RAX = a + b
soma:
    mov rax, rdi        ; RAX = a
    add rax, rsi        ; RAX = a + b
    ret

; Função fatorial(n) - retorna n!
; Parâmetros: RDI = n
; Retorno: RAX = n!
; Preserva: RBX (callee-saved)
fatorial:
    push rbx            ; Salva RBX (callee-saved)
    mov rbx, rdi        ; RBX = n
    cmp rbx, 1
    jle .base_case      ; Se n <= 1, retorna 1
    
    ; Recursão: n * fatorial(n-1)
    dec rdi             ; n-1
    call fatorial       ; RAX = fatorial(n-1)
    mul rbx             ; RAX = n * fatorial(n-1)
    jmp .done

.base_case:
    mov rax, 1

.done:
    pop rbx             ; Restaura RBX
    ret

; Função print_int(num) - imprime inteiro (syscall)
; Parâmetros: RDI = número
print_int:
    push rax
    push rdi
    push rsi
    push rdx
    
    ; Converte número para string (simplificado)
    mov rax, rdi
    add rax, '0'
    mov [buffer], al
    mov byte [buffer+1], 0xa   ; newline
    
    ; Syscall write
    mov rax, 1
    mov rdi, 1
    mov rsi, buffer
    mov rdx, 2
    syscall
    
    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

section .bss
    buffer resb 2

section .text
_start:
    ; Testa função soma
    mov rdi, 10
    mov rsi, 20
    call soma
    ; RAX = 30
    
    ; Testa função fatorial
    mov rdi, 5
    call fatorial
    ; RAX = 120
    
    ; Imprime resultado
    mov rdi, rax
    call print_int
    
    ; Finaliza
    mov rax, 60
    xor rdi, rdi
    syscall
```

### Convenção de Chamada MIPS (O32 ABI)

| Aspecto                       | Regra                                 |
| ----------------------------- | ------------------------------------- |
| **Argumentos**                | $a0, $a1, $a2, $a3 (até 4 argumentos) |
| **Retorno**                   | $v0, $v1                              |
| **Registradores temporários** | $t0-$t9 (caller-saved)                |
| **Registradores salvos**      | $s0-$s7 (callee-saved)                |
| **Pilha**                     | Alinhada a 8 bytes                    |

#### Exemplo Completo (MIPS)

```nasm
# funcoes.s - Exemplo de funções em MIPS
.data
    newline: .asciiz "\n"

.text
    .globl main

# Função soma(a, b) - retorna a + b
# Parâmetros: $a0 = a, $a1 = b
# Retorno: $v0 = a + b
soma:
    add $v0, $a0, $a1
    jr $ra

# Função fatorial(n) - retorna n!
# Parâmetros: $a0 = n
# Retorno: $v0 = n!
fatorial:
    addiu $sp, $sp, -8      # Espaço na pilha
    sw $ra, 0($sp)          # Salva return address
    sw $s0, 4($sp)          # Salva $s0 (callee-saved)
    
    move $s0, $a0           # $s0 = n
    li $v0, 1               # Valor padrão = 1
    ble $s0, 1, .base_case  # Se n <= 1, retorna 1
    
    # Recursão: n * fatorial(n-1)
    addiu $a0, $s0, -1      # $a0 = n-1
    jal fatorial            # $v0 = fatorial(n-1)
    mul $v0, $s0, $v0       # $v0 = n * fatorial(n-1)

.base_case:
    lw $ra, 0($sp)          # Restaura return address
    lw $s0, 4($sp)          # Restaura $s0
    addiu $sp, $sp, 8       # Libera pilha
    jr $ra

# Função print_int(num) - imprime inteiro (syscall)
# Parâmetros: $a0 = número
print_int:
    li $v0, 1               # syscall print_int
    syscall
    li $v0, 4               # syscall print_string
    la $a0, newline
    syscall
    jr $ra

main:
    # Testa soma
    li $a0, 10
    li $a1, 20
    jal soma                # $v0 = 30
    move $t0, $v0
    
    # Testa fatorial
    li $a0, 5
    jal fatorial            # $v0 = 120
    
    # Imprime resultado
    move $a0, $v0
    jal print_int
    
    # Finaliza
    li $v0, 10
    syscall
```

### Comparação com Outras Linguagens

**Python:**

```python
def quadrado(x):
    return x * x
result = quadrado(5)
```

* **Abstração**: Gerencia pilha e registradores automaticamente.
* **Tipagem**: Dinâmica, suporta múltiplos tipos.
* **Facilidade**: Sintaxe clara, ideal para iniciantes.

**Bash:**

```bash
quadrado() {
    echo $(($1 * $1))
}
result=$(quadrado 5)
```

* **Abstração**: Focado em scripts, argumentos via `$1`, `$2`.
* **Tipagem**: Strings por padrão, aritmética via `$(( ))`.
* **Limitações**: Menos eficiente para cálculos complexos.

**C:**

```c
int quadrado(int x) {
    return x * x;
}
int main() {
    int result = quadrado(5);
}
```

* **Abstração**: Mais próximo do hardware que Python/Bash.
* **Tipagem**: Estática, exige declaração de tipos.
* **Eficiência**: Compilado para código de máquina, próximo ao Assembly.

**Assembly:**

* **Abstração**: Mínima, exige gerenciamento manual de pilha/registradores.
* **Tipagem**: Não tipado, dados interpretados por instruções.
* **Eficiência**: Máxima, mas complexo e propenso a erros.

***

## Arrays no Assembly

### Definição e Manipulação

Arrays são blocos contínuos de memória acessados por índices. O programador gerencia endereços e deslocamentos.

#### x86-64

```nasm
section .data
    array dd 10, 20, 30, 40    ; Array de 4 inteiros (16 bytes)
    array2 times 100 dd 0      ; Array de 100 zeros

section .text
    ; Acessa elemento array[2] = 30
    mov eax, [array + 8]       ; Offset = índice * 4 (2 * 4 = 8)
    
    ; Atualiza elemento array[1] = 50
    mov ebx, 50
    mov [array + 4], ebx       ; Offset = 1 * 4 = 4
    
    ; Percorre array
    mov rcx, 4                 ; Tamanho
    mov rsi, array             ; Endereço base
loop_array:
    mov eax, [rsi]             ; Carrega elemento
    ; Processa elemento...
    add rsi, 4                 ; Próximo elemento (4 bytes)
    loop loop_array
```

#### MIPS

```nasm
.data
    array: .word 10, 20, 30, 40    # Array de 4 inteiros
    array2: .space 400             # Array de 100 zeros (4 * 100)

.text
    # Acessa elemento array[2] = 30
    la $t0, array
    lw $t1, 8($t0)                 # Offset = 2 * 4 = 8
    
    # Atualiza elemento array[1] = 50
    li $t2, 50
    sw $t2, 4($t0)                 # Offset = 1 * 4 = 4
    
    # Percorre array
    li $t3, 4                      # Tamanho
    la $t0, array                  # Endereço base
loop_array:
    lw $t1, 0($t0)                 # Carrega elemento
    # Processa elemento...
    addiu $t0, $t0, 4              # Próximo elemento
    addiu $t3, $t3, -1             # Decrementa contador
    bnez $t3, loop_array
```

### Arrays Bidimensionais (Matrizes)

Arrays bidimensionais são armazenados em ordem **row-major** (linhas consecutivas).

#### x86-64 - Matriz 3x3

```nasm
section .data
    ; Matriz 3x3 (row-major)
    matriz dd 1, 2, 3
           dd 4, 5, 6
           dd 7, 8, 9
    linhas equ 3
    colunas equ 3

section .text
    ; Acesso matriz[i][j] = base + (i * colunas + j) * 4
    ; Exemplo: matriz[1][2] = 6
    mov rax, 1                     ; i = 1
    mov rbx, 2                     ; j = 2
    mov rcx, colunas               ; colunas = 3
    imul rax, rcx                  ; rax = i * colunas
    add rax, rbx                   ; rax = i*colunas + j
    shl rax, 2                     ; rax = offset em bytes (*4)
    mov rsi, matriz
    add rsi, rax                   ; rsi = endereço do elemento
    mov eax, [rsi]                 ; eax = 6
```

### Função para Manipular Arrays

```nasm
; Função soma_array(arr, tamanho) - retorna soma dos elementos
; Parâmetros: RDI = endereço do array, RSI = tamanho
; Retorno: RAX = soma
soma_array:
    push rbx
    xor rax, rax        ; soma = 0
    xor rcx, rcx        ; contador = 0
.loop:
    cmp rcx, rsi
    jge .done
    mov ebx, [rdi + rcx*4]  ; carrega elemento
    add rax, rbx            ; soma += elemento
    inc rcx
    jmp .loop
.done:
    pop rbx
    ret
```

### Comparação com Outras Linguagens

**Python:**

```python
array = [10, 20, 30, 40]
array[2] = 50
for x in array:
    print(x)
```

* **Gerenciamento**: Dinâmico, redimensionável.
* **Tipagem**: Suporta múltiplos tipos.
* **Acesso**: Índices simples, verificação de limites.

**Bash:**

```bash
array=(10 20 30 40)
array[2]=50
for x in "${array[@]}"; do
    echo "$x"
done
```

* **Gerenciamento**: Estático, unidimensional.
* **Tipagem**: Strings por padrão.
* **Limitações**: Menos flexível para arrays complexos.

**C:**

```c
int array[] = {10, 20, 30, 40};
array[2] = 50;
for (int i = 0; i < 4; i++) {
    printf("%d\n", array[i]);
}
```

* **Gerenciamento**: Estático ou dinâmico (com `malloc`).
* **Tipagem**: Estática, tipo fixo por array.
* **Eficiência**: Próxima ao Assembly.

**Assembly:**

* **Gerenciamento**: Manual, offsets calculados.
* **Tipagem**: Não tipado, interpretação por instruções.
* **Eficiência**: Máxima, ideal para sistemas críticos.

***

## Estruturas (Structs) no Assembly

### Definição e Implementação

Assembly não suporta structs nativamente. **Estruturas de dados** são criadas como blocos de memória com campos acessados por deslocamentos fixos.

#### x86-64 - Estrutura Pessoa

```nasm
section .data
    ; Struct Pessoa:
    ; offset 0: nome[32] (32 bytes)
    ; offset 32: idade (4 bytes)
    ; offset 36: altura (4 bytes)
    ; Tamanho total: 40 bytes
    pessoa:
        nome times 32 db 0    ; 32 bytes para nome
        idade dd 25           ; 4 bytes para idade
        altura dd 165         ; 4 bytes para altura (cm)

    ; Array de estruturas
    pessoas:
        ; Pessoa 0
        nome0 times 32 db 0
        idade0 dd 20
        altura0 dd 170
        ; Pessoa 1
        nome1 times 32 db 0
        idade1 dd 25
        altura1 dd 165
        ; Pessoa 2
        nome2 times 32 db 0
        idade2 dd 30
        altura2 dd 180

    ; Constantes de offset
    PESSOA_NOME_OFFSET equ 0
    PESSOA_IDADE_OFFSET equ 32
    PESSOA_ALTURA_OFFSET equ 36
    PESSOA_SIZE equ 40

section .text
    ; Acessa pessoa.idade
    mov eax, [pessoa + PESSOA_IDADE_OFFSET]   ; eax = 25
    
    ; Modifica pessoa.idade
    mov dword [pessoa + PESSOA_IDADE_OFFSET], 26
    
    ; Acessa array de estruturas: pessoas[1].idade
    mov rsi, pessoas
    add rsi, PESSOA_SIZE * 1          ; pessoas[1]
    mov eax, [rsi + PESSOA_IDADE_OFFSET]  ; eax = 25
```

#### Usando `struc` (NASM)

```nasm
; Definição de estrutura com NASM
struc Pessoa
    .nome resb 32      ; offset 0
    .idade resd 1      ; offset 32
    .altura resd 1     ; offset 36
endstruc

section .data
    ; Aloca estrutura
    pessoa1:
        istruc Pessoa
            at Pessoa.nome, db 'Alice', 0
            at Pessoa.idade, dd 25
            at Pessoa.altura, dd 165
        iend

section .text
    ; Acessa usando offsets nomeados
    mov eax, [pessoa1 + Pessoa.idade]  ; eax = 25
    mov ebx, [pessoa1 + Pessoa.altura] ; ebx = 165
```

#### MIPS - Estrutura Pessoa

```nasm
.data
    # Constantes de offset
    .equ PESSOA_NOME_OFFSET, 0
    .equ PESSOA_IDADE_OFFSET, 32
    .equ PESSOA_ALTURA_OFFSET, 36
    .equ PESSOA_SIZE, 40
    
    # Struct Pessoa
    pessoa:
        .space 32          # nome (32 bytes)
        .word 25           # idade
        .word 165          # altura

.text
    # Acessa pessoa.idade
    la $t0, pessoa
    lw $t1, PESSOA_IDADE_OFFSET($t0)   # $t1 = 25
    
    # Modifica pessoa.idade
    li $t2, 26
    sw $t2, PESSOA_IDADE_OFFSET($t0)
```

### Função que Opera em Estruturas

```nasm
; incrementa_idade(pessoa) - incrementa idade em 1
; Parâmetros: RDI = endereço da estrutura
incrementa_idade:
    mov eax, [rdi + PESSOA_IDADE_OFFSET]  ; carrega idade
    inc eax                               ; incrementa
    mov [rdi + PESSOA_IDADE_OFFSET], eax  ; armazena
    ret

; Uso
_start:
    mov rdi, pessoa
    call incrementa_idade
```

### Comparação com Outras Linguagens

**Python:**

```python
class Pessoa:
    def __init__(self, nome, idade, altura):
        self.nome = nome
        self.idade = idade
        self.altura = altura

p = Pessoa("Alice", 25, 165)
p.idade += 1
```

* **Abstração**: Suporte nativo a objetos, encapsulamento.
* **Tipagem**: Dinâmica, flexível.
* **Facilidade**: Ideal para desenvolvimento rápido.

**Bash:**

```bash
declare -A pessoa
pessoa[nome]="Alice"
pessoa[idade]=25
pessoa[altura]=165
pessoa[idade]=$((pessoa[idade] + 1))
```

* **Abstração**: Arrays associativos simulam objetos.
* **Tipagem**: Strings, manipulação limitada.
* **Limitações**: Não escalável para objetos complexos.

**C:**

```c
struct Pessoa {
    char nome[32];
    int idade;
    int altura;
};

struct Pessoa p = {"Alice", 25, 165};
p.idade++;
```

* **Abstração**: Estruturas com campos, ponteiros para métodos.
* **Tipagem**: Estática, segura.
* **Eficiência**: Próxima ao Assembly.

**Assembly:**

* **Abstração**: Mínima, apenas blocos de memória.
* **Tipagem**: Não tipado, offsets manuais.
* **Eficiência**: Máxima, mas complexa.

***

## Gerenciamento de Pilha em Funções

### x86-64 - Prólogo e Epílogo

```nasm
minha_funcao:
    ; Prólogo - setup do stack frame
    push rbp                ; Salva base pointer anterior
    mov rbp, rsp            ; Configura novo base pointer
    sub rsp, 32             ; Reserva espaço para variáveis locais (16 bytes alinhado)
    
    ; Corpo da função
    mov dword [rbp-4], 10   ; Variável local
    mov dword [rbp-8], 20   ; Outra variável
    
    ; Chamada para outra função
    mov rdi, [rbp-4]
    call outra_funcao
    
    ; Epílogo - cleanup
    mov rsp, rbp            ; Libera espaço local
    pop rbp                 ; Restaura base pointer anterior
    ret
```

### MIPS - Prólogo e Epílogo

```nasm
minha_funcao:
    # Prólogo
    addiu $sp, $sp, -32     # Reserva espaço na pilha
    sw $ra, 28($sp)         # Salva return address
    sw $fp, 24($sp)         # Salva frame pointer
    move $fp, $sp           # Configura frame pointer
    
    # Corpo da função
    li $t0, 10
    sw $t0, 0($fp)          # Variável local
    li $t1, 20
    sw $t1, 4($fp)          # Outra variável
    
    # Chamada para outra função
    lw $a0, 0($fp)
    jal outra_funcao
    
    # Epílogo
    lw $ra, 28($sp)         # Restaura return address
    lw $fp, 24($sp)         # Restaura frame pointer
    addiu $sp, $sp, 32      # Libera pilha
    jr $ra
```

***

## Boas Práticas

### Funções

* **Siga convenções de chamada**: Preserve registradores callee-saved.
* **Documente parâmetros e retorno**: Comente o propósito da função.
* **Use prólogo/epílogo**: Mantenha a pilha organizada.
* **Limite profundidade de recursão**: Evite stack overflow.

### Arrays

* **Valide índices**: Evite acessos fora dos limites.
* **Use constantes para tamanhos**: Facilita manutenção.
* **Calcule offsets corretamente**: `(índice * tamanho_elemento)`.

### Estruturas

* **Documente offsets**: Use constantes ou `struc` (NASM).
* **Mantenha alinhamento**: Estruturas devem estar alinhadas para performance.
* **Agrupe campos relacionados**: Melhora localidade de cache.

***

## Comparação Resumida

| Estrutura      | Assembly (x86/MIPS)        | Python                | Bash               | C            |
| -------------- | -------------------------- | --------------------- | ------------------ | ------------ |
| **Funções**    | `CALL`/`JAL`, pilha manual | `def nome():`         | `nome() { ... }`   | `int nome()` |
| **Arrays**     | Blocos de memória, offsets | `[1, 2, 3]`, dinâmico | `array=(1 2 3)`    | `int arr[]`  |
| **Structs**    | Blocos de memória, offsets | `class` / `dataclass` | `declare -A`       | `struct`     |
| **Tipagem**    | Não tipado                 | Dinâmica              | Dinâmica (strings) | Estática     |
| **Eficiência** | Máxima                     | Moderada              | Baixa              | Alta         |

***

## Importância

Funções, arrays e estruturas em Assembly são cruciais para sistemas embarcados, drivers e otimização, oferecendo controle granular. Comparadas a Python, Bash e C, são mais eficientes, mas exigem maior esforço na implementação.

***

## 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)


---

# 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/3.-funcoes-and-objetos-and-arrays.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.
