# 8. Cheat Set   Manipulação de Memória

## Introdução

Este documento fornece uma referência rápida para manipulação de memória em Assembly, organizada como um guia "Ctrl+C Ctrl+V" para operações comuns. Abordaremos x86-64 e MIPS, com exemplos prontos para uso.

## 1. Carregar valor de memória

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Carrega 4 bytes (32 bits) do endereço em rax para ebx
mov ebx, [rax]

; Carrega 8 bytes (64 bits) do endereço em rsi para rdi
mov rdi, [rsi]

; Carrega byte (8 bits) com extensão de sinal
movsx eax, byte [rdx]

; Carrega byte (8 bits) sem extensão de sinal
movzx ebx, byte [rcx]

; Carrega word (16 bits) com extensão de sinal
movsx eax, word [r8]

; Carrega com deslocamento
mov eax, [rbx + 4]          ; rbx + 4
mov eax, [rbx + rcx*4]      ; rbx + rcx*4 (array)
mov eax, [rbx + rcx*4 + 8]  ; rbx + rcx*4 + 8
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
; Carrega palavra (32 bits) do endereço em $t0 para $t1
lw $t1, 0($t0)

; Carrega meia palavra (16 bits) com extensão de sinal
lh $t2, 0($t0)

; Carrega meia palavra (16 bits) sem extensão de sinal
lhu $t3, 0($t0)

; Carrega byte (8 bits) com extensão de sinal
lb $t4, 0($t0)

; Carrega byte (8 bits) sem extensão de sinal
lbu $t5, 0($t0)

; Carrega com deslocamento
lw $t1, 4($t0)              ; $t0 + 4
lw $t1, 8($t0)              ; $t0 + 8
```

{% endtab %}
{% endtabs %}

## 2. Armazenar valor em memória

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Armazena 4 bytes (32 bits) de ebx no endereço em rax
mov [rax], ebx

; Armazena 8 bytes (64 bits) de rdi no endereço em rsi
mov [rsi], rdi

; Armazena byte (8 bits) de al no endereço em rdx
mov [rdx], al

; Armazena word (16 bits) de ax no endereço em rcx
mov [rcx], ax

; Armazena com deslocamento
mov [rbx + 4], eax          ; rbx + 4
mov [rbx + rcx*4], eax      ; rbx + rcx*4 (array)
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
; Armazena palavra (32 bits) de $t1 no endereço em $t0
sw $t1, 0($t0)

; Armazena meia palavra (16 bits) de $t2
sh $t2, 0($t0)

; Armazena byte (8 bits) de $t3
sb $t3, 0($t0)

; Armazena com deslocamento
sw $t1, 4($t0)              ; $t0 + 4
sw $t1, 8($t0)              ; $t0 + 8
```

{% endtab %}
{% endtabs %}

## 3. Obter endereço de variável

{% tabs %}
{% tab title="x86-64" %}

```nasm
section .data
    var dd 42
    array dd 1, 2, 3, 4

section .text
    ; Obtém endereço de var em rax
    mov rax, var

    ; Ou usando LEA (Load Effective Address)
    lea rbx, [var]
    
    ; Endereço de elemento do array
    lea rcx, [array + 8]    ; array[2]
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
.data
    var: .word 42
    array: .word 1, 2, 3, 4

.text
    ; Obtém endereço de var em $t0
    la $t0, var
    
    ; Endereço de array[2] (8 bytes de offset)
    la $t1, array
    addiu $t1, $t1, 8
```

{% endtab %}
{% endtabs %}

## 4. Aritmética de ponteiros

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Avança ponteiro em 4 bytes (int)
add rax, 4

; Recua ponteiro em 8 bytes (double)
sub rbx, 8

; Acesso indexado (array[i] onde i está em rcx)
mov edx, [rax + rcx*4]      ; Para array de int (4 bytes)
mov edx, [rax + rcx*2]      ; Para array de short (2 bytes)
mov dl, [rax + rcx]         ; Para array de char (1 byte)

; Acesso com base + índice + deslocamento
mov edx, [rax + rcx*4 + 16] ; array[i+4]
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
; Avança ponteiro em 4 bytes
addiu $t0, $t0, 4

; Recua ponteiro em 8 bytes
addiu $t1, $t1, -8

; Acesso indexado (array[i] onde i está em $t2)
sll $t3, $t2, 2             ; Multiplica índice por 4 (para int)
addu $t4, $t0, $t3          ; Calcula endereço
lw $t5, 0($t4)              ; Carrega array[i]

; Acesso com deslocamento constante
lw $t5, 8($t0)              ; array + 2 (índice 2 para int)
```

{% endtab %}
{% endtabs %}

## 5. Alocação estática

{% tabs %}
{% tab title="x86-64" %}

```nasm
section .data
    ; Aloca 1 byte inicializado
    byte1 db 0x55
    
    ; Aloca 2 bytes inicializado
    word1 dw 0x1234
    
    ; Aloca 4 bytes (32 bits) inicializado
    dword1 dd 0x12345678
    
    ; Aloca 8 bytes (64 bits) inicializado
    qword1 dq 0x123456789ABCDEF0
    
    ; Aloca string
    string db 'Hello', 0
    
    ; Aloca array de 10 bytes inicializados
    array db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    
    ; Aloca 100 bytes inicializados com zeros
    zeros times 100 db 0

section .bss
    ; Aloca 1 byte não inicializado
    buffer1 resb 1
    
    ; Aloca 4 bytes não inicializados
    buffer4 resd 1
    
    ; Aloca 100 bytes não inicializados
    buffer100 resb 100
    
    ; Aloca array de 10 inteiros (40 bytes)
    int_array resd 10
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
.data
    # Aloca 1 byte inicializado
    byte1: .byte 0x55
    
    # Aloca 2 bytes inicializado
    half1: .half 0x1234
    
    # Aloca 4 bytes (32 bits) inicializado
    word1: .word 0x12345678
    
    # Aloca 8 bytes (64 bits) inicializado
    dword1: .double 0x123456789ABCDEF0
    
    # Aloca string
    string: .asciiz "Hello"
    
    # Aloca array de 10 bytes inicializados
    array: .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    
    # Aloca 100 bytes inicializados com zeros
    zeros: .space 100

.bss
    # Aloca 1 byte não inicializado
    buffer1: .space 1
    
    # Aloca 4 bytes não inicializado
    buffer4: .space 4
    
    # Aloca 100 bytes não inicializados
    buffer100: .space 100
    
    # Aloca array de 10 inteiros (40 bytes)
    int_array: .space 40
```

{% endtab %}
{% endtabs %}

## 6. Alocação dinâmica

{% tabs %}
{% tab title="x86-64 (Linux syscall - brk)" %}

```nasm
section .text
    global _start

_start:
    ; Aloca 1024 bytes via brk
    mov rax, 12         ; syscall brk
    xor rdi, rdi        ; NULL para obter endereço atual
    syscall
    mov [current_brk], rax

    ; Estende heap em 1024 bytes
    mov rdi, rax
    add rdi, 1024
    mov rax, 12         ; syscall brk
    syscall

    ; Uso da memória alocada
    mov rdi, [current_brk]
    mov dword [rdi], 1234  ; Armazena valor

    ; Encerra
    mov rax, 60
    xor rdi, rdi
    syscall

section .bss
    current_brk resq 1
```

{% endtab %}

{% tab title="x86-64 (Linux syscall - mmap) - Mais Moderno" %}

```nasm
; Alocação com mmap (mais moderno e flexível)
section .text
    global _start

_start:
    ; mmap(addr, length, prot, flags, fd, offset)
    mov rax, 9          ; syscall mmap
    mov rdi, 0          ; addr (NULL - kernel escolhe)
    mov rsi, 4096       ; length (página)
    mov rdx, 3          ; PROT_READ | PROT_WRITE (1+2)
    mov r10, 0x22       ; MAP_PRIVATE | MAP_ANONYMOUS
    mov r8, -1          ; fd (ignorado para MAP_ANONYMOUS)
    mov r9, 0           ; offset
    syscall
    
    ; Verifica erro
    cmp rax, -4095
    ja .erro
    
    ; Uso da memória alocada
    mov rdi, rax        ; endereço alocado
    mov dword [rdi], 42
    
    ; Libera memória (munmap)
    mov rax, 11         ; syscall munmap
    mov rsi, 4096       ; length
    syscall

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

{% endtab %}

{% tab title="MIPS (Linux syscall - sbrk)" %}

```nasm
.text
    .globl main
main:
    # Aloca 1024 bytes via sbrk
    li $v0, 9           # syscall sbrk
    li $a0, 1024        # tamanho
    syscall
    move $t0, $v0       # salva ponteiro

    # Uso da memória alocada
    li $t1, 1234
    sw $t1, 0($t0)      # armazena valor

    # Encerra
    li $v0, 10
    syscall
```

{% endtab %}
{% endtabs %}

## 7. Copiar blocos de memória

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Copia 64 bytes de src para dest
mov rsi, src           ; origem
mov rdi, dest          ; destino
mov rcx, 64            ; contador (64 bytes)
rep movsb              ; copia byte a byte

; Alternativa mais rápida para blocos alinhados
mov rsi, src
mov rdi, dest
mov rcx, 8             ; 8 qwords = 64 bytes
rep movsq              ; copia 8 bytes por vez

; Copia usando loop manual
copy_loop:
    mov al, [rsi]
    mov [rdi], al
    inc rsi
    inc rdi
    dec rcx
    jnz copy_loop
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
.data
    src: .space 64
    dest: .space 64

.text
    la $t0, src        # origem
    la $t1, dest       # destino
    li $t2, 64         # contador

copy_loop:
    beqz $t2, end_copy
    lb $t3, 0($t0)     # carrega byte
    sb $t3, 0($t1)     # armazena byte
    addiu $t0, $t0, 1  # incrementa origem
    addiu $t1, $t1, 1  # incrementa destino
    addiu $t2, $t2, -1 # decrementa contador
    j copy_loop

end_copy:
```

{% endtab %}
{% endtabs %}

## 8. Preencher blocos de memória

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Preenche 256 bytes com 0xAA
mov rdi, buffer        ; destino
mov al, 0xAA           ; valor
mov rcx, 256           ; contador
rep stosb              ; preenche

; Preenche com DWORDs (4 bytes)
mov rdi, buffer
mov eax, 0xDEADBEEF    ; valor
mov rcx, 64            ; 256/4 = 64 DWORDs
rep stosd

; Preenche com QWORDs (8 bytes)
mov rdi, buffer
mov rax, 0xDEADBEEFDEADBEEF
mov rcx, 32            ; 256/8 = 32 QWORDs
rep stosq
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
.data
    buffer: .space 256

.text
    la $t0, buffer     # destino
    li $t1, 0xAA       # valor
    li $t2, 256        # contador

fill_loop:
    beqz $t2, end_fill
    sb $t1, 0($t0)     # armazena byte
    addiu $t0, $t0, 1  # incrementa destino
    addiu $t2, $t2, -1 # decrementa contador
    j fill_loop

end_fill:
```

{% endtab %}
{% endtabs %}

## 9. Comparar blocos de memória

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Compara dois blocos de memória
; Parâmetros: RDI = bloco1, RSI = bloco2, RCX = tamanho
; Retorno: ZF=1 se iguais
compare_blocks:
    repe cmpsb
    ret

; Uso
mov rdi, bloco1
mov rsi, bloco2
mov rcx, 64
call compare_blocks
je iguais
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
# Compara dois blocos de memória
# Parâmetros: $a0 = bloco1, $a1 = bloco2, $a2 = tamanho
# Retorno: $v0 = 1 se iguais, 0 se diferentes
compare_blocks:
    move $t0, $a0
    move $t1, $a1
    move $t2, $a2
    li $v0, 1

compare_loop:
    beqz $t2, compare_done
    lb $t3, 0($t0)
    lb $t4, 0($t1)
    bne $t3, $t4, compare_diff
    addiu $t0, $t0, 1
    addiu $t1, $t1, 1
    addiu $t2, $t2, -1
    j compare_loop

compare_diff:
    li $v0, 0

compare_done:
    jr $ra
```

{% endtab %}
{% endtabs %}

## 10. Alinhamento de memória

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Alinhamento em seções
section .data
    align 16            ; Alinha próximo dado a 16 bytes
    var1 dd 1
    
    align 8
    var2 dq 2

section .bss
    align 32
    buffer resb 64      ; Buffer alinhado a 32 bytes (para AVX)

; Alinhamento dinâmico
align_to_16:
    add rdi, 15
    and rdi, 0xFFFFFFFFFFFFFFF0  ; Alinha para múltiplo de 16
    ret
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
.data
    .align 2            # Alinha a 4 bytes (2^2)
    word1: .word 1
    
    .align 3            # Alinha a 8 bytes (2^3)
    double1: .double 3.14
```

{% endtab %}
{% endtabs %}

## 11. Pilha (Stack)

{% tabs %}
{% tab title="x86-64" %}

```nasm
; Empilhar valores
push rax                ; Empilha RAX (8 bytes)
push rbx                ; Empilha RBX
push rcx                ; Empilha RCX

; Desempilhar valores
pop rcx                 ; Desempilha para RCX
pop rbx                 ; Desempilha para RBX
pop rax                 ; Desempilha para RAX

; Reservar espaço na pilha
sub rsp, 32             ; Reserva 32 bytes
; ... uso ...
add rsp, 32             ; Libera espaço

; Acessar variáveis locais
sub rsp, 8
mov [rsp], rax          ; Armazena na pilha
mov rbx, [rsp]          ; Carrega da pilha
add rsp, 8
```

{% endtab %}

{% tab title="MIPS" %}

```nasm
; Empilhar valores (usando $sp)
addiu $sp, $sp, -4      ; Reserva 4 bytes
sw $t0, 0($sp)          ; Empilha $t0

addiu $sp, $sp, -4
sw $t1, 0($sp)          ; Empilha $t1

; Desempilhar valores
lw $t1, 0($sp)          ; Desempilha para $t1
addiu $sp, $sp, 4
lw $t0, 0($sp)
addiu $sp, $sp, 4

; Reservar espaço para variáveis locais
addiu $sp, $sp, -32     ; Reserva 32 bytes
; ... uso ...
addiu $sp, $sp, 32      ; Libera espaço
```

{% endtab %}
{% endtabs %}

## Tabela de Referência Rápida

| Operação                      | x86-64            | MIPS                 |
| ----------------------------- | ----------------- | -------------------- |
| **Carregar 32 bits**          | `mov eax, [rbx]`  | `lw $t0, 0($t1)`     |
| **Carregar 8 bits**           | `mov al, [rbx]`   | `lb $t0, 0($t1)`     |
| **Armazenar 32 bits**         | `mov [rax], ebx`  | `sw $t0, 0($t1)`     |
| **Obter endereço**            | `lea rax, [var]`  | `la $t0, var`        |
| **Incrementar ptr**           | `add rax, 4`      | `addiu $t0, $t0, 4`  |
| **Alocação estática (.data)** | `var dd 42`       | `var: .word 42`      |
| **Alocação estática (.bss)**  | `buffer resb 100` | `buffer: .space 100` |
| **Alocação dinâmica**         | `mmap` / `brk`    | `sbrk` (syscall 9)   |
| **Copiar memória**            | `rep movsb`       | Loop com `lb`/`sb`   |
| **Preencher memória**         | `rep stosb`       | Loop com `sb`        |
| **Comparar memória**          | `repe cmpsb`      | Loop com `lb`        |

## Dicas de Uso

1. **Para copiar blocos**: Use `rep movsb` (x86) ou loop com `lb`/`sb` (MIPS)
2. **Para alocar**: Use seção `.data` para constantes, `.bss` para buffers grandes
3. **Para acesso a arrays**: Use aritmética de ponteiros com multiplicação por tamanho
4. **Para inicialização**: Use alocação estática com valores iniciais
5. **Para performance**: Prefira alinhamento de 16 bytes para operações SIMD
6. **Para segurança**: Sempre verifique limites de buffer

## Recursos Adicionais

* **Manual Intel**: [Volume 2A](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html)
* **NASM Manual**: [nasm.us/doc](https://nasm.us/doc/)
* **MIPS Reference**: [MIPS Architecture](https://www.mips.com/products/architectures/)
* **GDB Cheat Sheet**: [gdb-tutorial.net](https://www.gdb-tutorial.net/)


---

# 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/8.-cheat-set-manipulacao-de-memoria.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.
