# 4. Marizes

## 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 **matrizes** (arrays bidimensionais), detalhando sua implementação, manipulação, boas práticas e uma comparação 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 que acessa um elemento de uma matriz:

```nasm
section .data
    matriz dd 1, 2, 3    ; Linha 0
           dd 4, 5, 6    ; Linha 1
    linhas equ 2
    colunas equ 3

section .text
    global _start

_start:
    mov rsi, matriz      ; Endereço base
    mov rax, 1           ; Linha 1
    mov rbx, 2           ; Coluna 2
    mov rcx, colunas     ; Colunas por linha
    imul rax, rcx        ; rax = linha * colunas
    add rax, rbx         ; rax = linha * colunas + coluna
    shl rax, 2           ; Multiplica por 4 (tamanho de dd)
    add rsi, rax         ; Endereço do elemento
    mov eax, [rsi]       ; Carrega elemento (6)

    mov rax, 60          ; Syscall sair
    xor rdi, rdi
    syscall
```

* `section .data`: Define dados inicializados (como a matriz).
* `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` |
| `IMUL`        | Multiplicação com sinal                   | `imul rax, rcx` | `mul $t0, $t1, $t2` |
| `SHL` / `SLL` | Shift left (multiplica por potência de 2) | `shl rax, 2`    | `sll $t0, $t0, 2`   |

### Manipulação de Memória

| Arquitetura | Leitura          | Escrita          |
| ----------- | ---------------- | ---------------- |
| x86-64      | `mov eax, [rsi]` | `mov [rsi], 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 |
| `LOOP label`    | `addiu $t0, -1; bnez` | Loop com contador   |

***

## Matrizes no Assembly

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

Matrizes em Assembly são arrays bidimensionais armazenados como blocos contínuos de memória, geralmente em ordem **row-major** (linhas consecutivas). O acesso a um elemento em uma matriz `M[i][j]` requer o cálculo do endereço:

```
endereço = base + (i * colunas + j) * tamanho_elemento
```

#### x86-64 - Definição de Matrizes

```nasm
section .data
    ; Matriz 2x3 (row-major)
    matriz_2x3 dd 1, 2, 3    ; Linha 0
               dd 4, 5, 6    ; Linha 1
    linhas_2x3 equ 2
    colunas_2x3 equ 3

    ; Matriz 3x3
    matriz_3x3 dd 1, 2, 3
               dd 4, 5, 6
               dd 7, 8, 9
    linhas_3x3 equ 3
    colunas_3x3 equ 3

    ; Matriz 4x4 com zeros
    matriz_4x4 times 16 dd 0
    linhas_4x4 equ 4
    colunas_4x4 equ 4

    ; Matriz de bytes (8 bits)
    matriz_bytes db 1, 2, 3
                 db 4, 5, 6
    linhas_bytes equ 2
    colunas_bytes equ 3
```

### Acesso a Elementos

#### x86-64 - Acesso e Modificação

```nasm
section .text
    ; Acesso matriz_2x3[1][2] = 6
    mov rsi, matriz_2x3      ; Endereço base
    mov rax, 1               ; i = 1
    mov rbx, 2               ; j = 2
    mov rcx, colunas_2x3     ; colunas = 3
    imul rax, rcx            ; rax = i * colunas
    add rax, rbx             ; rax = i*colunas + j
    shl rax, 2               ; rax *= 4 (tamanho de dd)
    add rsi, rax             ; rsi = endereço do elemento
    mov eax, [rsi]           ; eax = 6

    ; Modifica matriz_2x3[1][2] = 10
    mov dword [rsi], 10      ; Armazena 10 no endereço

    ; Acesso matriz_bytes[1][2]
    mov rsi, matriz_bytes
    mov rax, 1
    mov rbx, 2
    mov rcx, colunas_bytes
    imul rax, rcx
    add rax, rbx
    ; Para bytes, não multiplica por 4
    add rsi, rax
    mov al, [rsi]            ; al = 6
```

#### MIPS - Acesso e Modificação

```nasm
.data
    # Matriz 2x3
    matriz: .word 1, 2, 3
            .word 4, 5, 6
    linhas: .word 2
    colunas: .word 3

.text
    # Acesso matriz[1][2] = 6
    la $t0, matriz           # Endereço base
    li $t1, 1                # i = 1
    li $t2, 2                # j = 2
    lw $t3, colunas          # colunas = 3
    mul $t4, $t1, $t3        # $t4 = i * colunas
    add $t4, $t4, $t2        # $t4 = i*colunas + j
    sll $t4, $t4, 2          # $t4 *= 4 (tamanho de word)
    add $t0, $t0, $t4        # $t0 = endereço do elemento
    lw $t5, 0($t0)           # $t5 = 6
    
    # Modifica matriz[1][2] = 10
    li $t6, 10
    sw $t6, 0($t0)
```

### Função para Acesso Genérico

```nasm
; Função get_matriz_elemento(matriz, i, j, colunas, tamanho)
; Parâmetros: RDI = endereço base, RSI = i, RDX = j, RCX = colunas, R8 = tamanho_elemento
; Retorno: RAX = valor do elemento
get_matriz_elemento:
    mov rax, rsi            ; rax = i
    imul rax, rcx           ; rax = i * colunas
    add rax, rdx            ; rax = i*colunas + j
    imul rax, r8            ; rax *= tamanho_elemento
    add rax, rdi            ; rax = endereço final
    mov rax, [rax]          ; carrega valor
    ret

; Uso: obter matriz_2x3[1][2]
    mov rdi, matriz_2x3
    mov rsi, 1
    mov rdx, 2
    mov rcx, colunas_2x3
    mov r8, 4               ; tamanho de dd
    call get_matriz_elemento
```

***

## Iteração sobre Matrizes

### Percorrer Todos os Elementos

#### x86-64 - Loop Aninhado

```nasm
; Percorre matriz 2x3 e soma todos elementos
section .text
soma_matriz:
    mov rsi, matriz_2x3      ; Endereço base
    xor rax, rax             ; soma = 0
    mov rcx, 0               ; i = 0
loop_i:
    cmp rcx, linhas_2x3
    jge fim_soma
    mov rdx, 0               ; j = 0
loop_j:
    cmp rdx, colunas_2x3
    jge prox_linha
    ; Calcula offset
    mov rbx, rcx
    imul rbx, colunas_2x3
    add rbx, rdx
    shl rbx, 2
    ; Soma elemento
    add rax, [rsi + rbx]
    inc rdx
    jmp loop_j
prox_linha:
    inc rcx
    jmp loop_i
fim_soma:
    ret
```

#### x86-64 - Otimizado com Ponteiros

```nasm
; Percorre matriz usando ponteiro único (mais eficiente)
soma_matriz_otimizado:
    mov rsi, matriz_2x3       ; Ponteiro atual
    mov rcx, linhas_2x3
    imul rcx, colunas_2x3     ; Total de elementos
    xor rax, rax              ; soma = 0
loop:
    add eax, [rsi]            ; Soma elemento
    add rsi, 4                ; Próximo elemento (4 bytes)
    loop loop                 ; Decrementa RCX e repete
    ret
```

#### MIPS - Loop Aninhado

```nasm
# Percorre matriz 2x3 e soma todos elementos
.data
    matriz: .word 1, 2, 3, 4, 5, 6
    linhas: .word 2
    colunas: .word 3

.text
soma_matriz:
    la $t0, matriz           # Endereço base
    li $t1, 0                # i = 0
    li $t2, 0                # soma = 0
    lw $t3, linhas
    lw $t4, colunas
    
loop_i:
    bge $t1, $t3, fim_soma
    li $t5, 0                # j = 0
loop_j:
    bge $t5, $t4, prox_linha
    # Calcula offset
    mul $t6, $t1, $t4        # i * colunas
    add $t6, $t6, $t5        # i*colunas + j
    sll $t6, $t6, 2          # *4
    add $t7, $t0, $t6        # endereço
    lw $t8, 0($t7)           # elemento
    add $t2, $t2, $t8        # soma += elemento
    addiu $t5, $t5, 1
    j loop_j
prox_linha:
    addiu $t1, $t1, 1
    j loop_i
fim_soma:
    move $v0, $t2            # retorna soma
    jr $ra
```

***

## Operações com Matrizes

### Soma de Duas Matrizes

#### x86-64 - Soma de Matrizes

```nasm
section .data
    matriz_A dd 1, 2, 3
             dd 4, 5, 6
    matriz_B dd 7, 8, 9
             dd 10, 11, 12
    matriz_C times 6 dd 0    ; Matriz resultado
    linhas equ 2
    colunas equ 3

section .text
soma_matrizes:
    mov rsi, matriz_A        ; Matriz A
    mov rdi, matriz_B        ; Matriz B
    mov rbx, matriz_C        ; Matriz resultado
    mov rcx, linhas
    imul rcx, colunas        ; Total de elementos
    xor rdx, rdx             ; Contador
loop_soma:
    cmp rdx, rcx
    jge fim_soma
    mov eax, [rsi + rdx*4]   ; elemento de A
    add eax, [rdi + rdx*4]   ; + elemento de B
    mov [rbx + rdx*4], eax   ; armazena em C
    inc rdx
    jmp loop_soma
fim_soma:
    ret
```

### Multiplicação de Matrizes

#### x86-64 - Multiplicação de Matrizes (3x3)

```nasm
section .data
    mat_A dd 1, 2, 3
          dd 4, 5, 6
          dd 7, 8, 9
    mat_B dd 9, 8, 7
          dd 6, 5, 4
          dd 3, 2, 1
    mat_C times 9 dd 0
    N equ 3                  ; Dimensão

section .text
multiplica_matrizes:
    ; C[i][j] = sum_k (A[i][k] * B[k][j])
    xor rsi, rsi             ; i = 0
loop_i:
    cmp rsi, N
    jge fim_multiplica
    xor rdi, rdi             ; j = 0
loop_j:
    cmp rdi, N
    jge prox_i
    xor rax, rax             ; soma = 0
    xor rcx, rcx             ; k = 0
loop_k:
    cmp rcx, N
    jge store_result
    ; A[i][k] = base_A + (i*N + k)*4
    mov r8, rsi
    imul r8, N
    add r8, rcx
    shl r8, 2
    mov r9, mat_A
    add r9, r8
    mov r10d, [r9]           ; A[i][k]
    ; B[k][j] = base_B + (k*N + j)*4
    mov r8, rcx
    imul r8, N
    add r8, rdi
    shl r8, 2
    mov r9, mat_B
    add r9, r8
    mov r11d, [r9]           ; B[k][j]
    ; soma += A[i][k] * B[k][j]
    imul r10d, r11d
    add eax, r10d
    inc rcx
    jmp loop_k
store_result:
    ; mat_C[i][j] = soma
    mov r8, rsi
    imul r8, N
    add r8, rdi
    shl r8, 2
    mov r9, mat_C
    add r9, r8
    mov [r9], eax
    inc rdi
    jmp loop_j
prox_i:
    inc rsi
    jmp loop_i
fim_multiplica:
    ret
```

### Transposição de Matriz

#### x86-64 - Transposição de Matriz

```nasm
; Transpõe matriz quadrada NxN
; Parâmetros: RDI = matriz, RSI = N
transpor_matriz:
    push rbx
    push r12
    push r13
    
    mov r12, rdi            ; matriz
    mov r13, rsi            ; N
    xor rbx, rbx            ; i = 0
loop_i_trans:
    cmp rbx, r13
    jge fim_trans
    mov rcx, rbx
    inc rcx                 ; j = i + 1
loop_j_trans:
    cmp rcx, r13
    jge prox_i_trans
    ; Calcular endereços A[i][j] e A[j][i]
    ; A[i][j] = base + (i*N + j)*4
    mov rax, rbx
    imul rax, r13
    add rax, rcx
    shl rax, 2
    add rax, r12
    ; A[j][i] = base + (j*N + i)*4
    mov rdx, rcx
    imul rdx, r13
    add rdx, rbx
    shl rdx, 2
    add rdx, r12
    ; Trocar valores
    mov r8d, [rax]
    mov r9d, [rdx]
    mov [rax], r9d
    mov [rdx], r8d
    inc rcx
    jmp loop_j_trans
prox_i_trans:
    inc rbx
    jmp loop_i_trans
fim_trans:
    pop r13
    pop r12
    pop rbx
    ret
```

***

## Alinhamento de Matrizes

Para performance, matrizes devem estar alinhadas na memória.

```nasm
section .data
    align 16                ; Alinha a 16 bytes (para SSE)
    matriz_alinhada times 64 dd 0  ; Matriz 8x8 alinhada

section .bss
    align 32                ; Alinha a 32 bytes (para AVX)
    matriz_avx resd 256     ; Matriz 16x16
```

***

## Comparação com Outras Linguagens

| Aspecto        | Assembly (x86/MIPS)           | Python                      | Bash                | C                     |
| -------------- | ----------------------------- | --------------------------- | ------------------- | --------------------- |
| **Definição**  | Blocos contínuos, row-major   | Listas aninhadas, dinâmicas | Arrays associativos | Arrays bidimensionais |
| **Acesso**     | `(i * colunas + j) * tamanho` | `matriz[i][j]`              | `${matriz[i,j]}`    | `matriz[i][j]`        |
| **Iteração**   | Loops manuais com offset      | `for linha in matriz`       | Loops aninhados     | Loops aninhados       |
| **Tipagem**    | Não tipado, manual            | Dinâmica, flexível          | Strings             | Estática, fixa        |
| **Eficiência** | Máxima, mas complexa          | Menor, mas simples          | Baixa, script-based | Alta, compilada       |

### Exemplo em Python

```python
matriz = [[1, 2, 3], [4, 5, 6]]
matriz[1][2] = 10
for linha in matriz:
    for elemento in linha:
        print(elemento)
```

### Exemplo em Bash

```bash
declare -A matriz
matriz[0,0]=1 matriz[0,1]=2 matriz[0,2]=3
matriz[1,0]=4 matriz[1,1]=5 matriz[1,2]=6
matriz[1,2]=10
for i in {0..1}; do
    for j in {0..2}; do
        echo "${matriz[$i,$j]}"
    done
done
```

### Exemplo em C

```c
int matriz[2][3] = {{1, 2, 3}, {4, 5, 6}};
matriz[1][2] = 10;
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        printf("%d\n", matriz[i][j]);
    }
}
```

***

## Boas Práticas com Matrizes

{% stepper %}
{% step %}

### 1. Cálculo de Offsets

* Use constantes para dimensões
* Documente a fórmula de acesso
* Valide índices antes de acessar

```nasm
; Exemplo de validação
    cmp rax, linhas
    jae erro_indice
    cmp rbx, colunas
    jae erro_indice
```

{% endstep %}

{% step %}

### 2. Alinhamento

* Alinhe matrizes para melhor performance
* Use `align` antes de dados importantes

```nasm
section .data
    align 16
    matriz_float dq 1.0, 2.0, 3.0  ; Para SSE
```

{% endstep %}

{% step %}

### 3. Iteração Eficiente

* Use ponteiro único para percorrer matrizes
* Aproveite localidade de cache

```nasm
; Eficiente: percorre em ordem de memória
    mov rsi, matriz
    mov rcx, total_elementos
loop:
    mov eax, [rsi]
    ; processa...
    add rsi, 4
    loop loop
```

{% endstep %}

{% step %}

### 4. Documentação

* Comente as dimensões da matriz
* Explique o armazenamento (row-major vs column-major)
  {% endstep %}
  {% endstepper %}

***

## Ferramentas para Depuração

| Comando             | Finalidade             |
| ------------------- | ---------------------- |
| `gdb`               | Depuração interativa   |
| `layout asm`        | Visualização assembly  |
| `x/10x $rsi`        | Examinar memória       |
| `watch *0x7fffffff` | Watchpoint em endereço |
| `objdump -d`        | Desmontar binário      |

***

## Exemplo Completo: Soma de Matrizes 3x3

```nasm
; soma_matrizes.asm - Soma de duas matrizes 3x3
section .data
    ; Matriz A
    A dd 1, 2, 3
      dd 4, 5, 6
      dd 7, 8, 9
    
    ; Matriz B
    B dd 9, 8, 7
      dd 6, 5, 4
      dd 3, 2, 1
    
    ; Matriz resultado
    C times 9 dd 0
    
    N equ 3
    ELEMENT_SIZE equ 4

section .text
    global _start

_start:
    ; Soma as matrizes
    mov rsi, A
    mov rdi, B
    mov rbx, C
    mov rcx, N * N           ; Total de elementos
    xor rdx, rdx             ; Contador

soma_loop:
    cmp rdx, rcx
    jge fim_soma
    mov eax, [rsi + rdx*4]
    add eax, [rdi + rdx*4]
    mov [rbx + rdx*4], eax
    inc rdx
    jmp soma_loop

fim_soma:
    ; Aqui poderia exibir resultado
    ; (syscall write para imprimir matriz)
    
    ; Finaliza programa
    mov rax, 60
    xor rdi, rdi
    syscall
```

***

## 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))
* **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/4.-marizes.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.
