Ir para conteúdo

Dicas sobre Assembly


Lincoln Arantes

Posts Recomendados

 

Sou apaixonado pela linguagem Assembly e espero que você goste também!

Autor: Lincoln César dos Reis Arantes - Analista de Sistema (graduado)

Registradores x86 – IA 32


 

Registradores são memórias rápidas que ficam no processador com uma finalidade especifica.


 

image.png.12f4b69995d7d3c45eaeb1a63d30a93f.png


 

Registradores para uso geral!

Segue abaixo os principais registradores para uso geral:

De 16 bits:

AX – Acumulador

BX – Base

CX – Contador

DX – Dados


 


 

SI – Source Index –índice de origem de dados

DI – Destination Index – índice de destino

BP – Base Pointer – Apontador de base

SP – Stack Pointer – Apontador para o topo da pilha

IP – Instruction Pointer – Apontador de próxima instrução a ser executada.


 

De 32 bits:

EAX - Acumulador

Pode ser usado em operações aritméticas.

EBX - Base

Pode ser usado para apontar para dados.

ECX - Contador

Pode ser usado em alguns casos em loops para contar os laços de repetição.

EDX - Registrador de Dados em geral

Vários casos, pode ser usado em multiplicações e divisões e em outros casos como entrada e saída.


 

Perceba que no caso de 32 bits foi adicionado o E na frente do registrador!


 

ESP - Apontador da Pilha -Stack pointer.

EBP - Apontador da base - Base pointer.

ESI - Índice de origem.

EDI - Índice do destino.


 


 

Registradores de Segmentos

CS-Segmento do código (Code segment)

DS-Segmento de dados (Data segment)

SS-Segmento de Pilha (Stack segment)

ES-Segmento com dados extra (Extra segment)

FS-Segmento com dados extra (Extra segment)

GS-Segmento com dados extra (Extra segment)


 

Registradores de Flags

São registros de controles ou melhor sinalizadores para o processador, geralmente funcionam como testadores.

Tabela de Flags de 16 bits.

Observação: 7 bits não são usados

Flag:

 

 

 

 

OF

DF

IF

TF

SF

ZF

 

AF

 

PF

 

CF

Ordem bits:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0


 


 

  • Overflow Flag (OF) - Exibe o estouro de um bit de alta ordem após uma operação matemática.

  • Direction Flag (DF) - Determina a direção esquerda ou direita para mover ou comparar dados de string. 

  • Interrupt Flag (IF) - Determina se as interrupções externas, como entrada de teclado e outros devem ser ignoradas ou processadas.

  • Trap Flag (TF) - Deixa configurar uma operação do processador de uma única vez.

  • Sign Flag (SF) - Exibe o sinal do resultado de uma operação matemática. 

  • Zero Flag (ZF) - Indica o resultado de uma operação matemática ou de comparação. 

  • Auxiliary Carry Flag (AF) - Contém o carry do bit 3 ao bit 4 após uma operação matemática; usado para aritmética especializada. 

  • Parity Flag (PF) - Mostra o número total de 1-bit no resultado obtido de uma operação matemática. 

  • Carry Flag (CF) - Contém o carry de 0 ou 1 de um bit de alta ordem (mais à esquerda) após uma operação matemática. 


 


 

Apesar de existirem registradores de 64 bits, não focaremos nele no momento, mas só por efeito de sabedoria os básicos deles são eles: rax, rbx, rcx, rdx.


 


 

Estrutura de um código Assembly

Seção de texto:

section .text

Na linguagem c, o main informa onde começar o programa, no assembly, na seção text deve ter a declaração global _start para que o kernel entenda onde iniciar o programa.

Aqui é colocado o código do programa


 


 

Seção de dados:

section .data

Geralmente usado para declarar constantes e dados em geral. (Dados não mudam)


 


 

Seção de informações de variáveis:

section .bss

Geralmente usada para declaração de variáveis.


 


 


 

Chamadas de sistema


 

Chamadas de sistema (System Calls) são APIS que serve de interface entre programador e o kernel do Sistema Operacional.

Quando estamos programando utilizamos bastante de chamadas de sistema.


 

Para facilitar o entendimento colocarei aqui as chamadas mais comuns. Observe o exemplo:


 

Exemplo o abaixo é um sys_write ou chamada de sistema de escrita.


 

mov edx,4 ; Tamanho da mensagem

mov ecx, mensagem ; mensagem a ser escrita

mov ebx,1 ; file descriptor (stdout)

mov eax,4 ; Número da chamada do sistema

int 0x80 ; Chamada no kernel


 

Usado quando precisamos mostrar uma mensagem na tela ou em outros casos para mostrar variáveis em geral.


 

Agora, vejamos uma outra chamada também bastante usada, no caso é a sys_read ou chamada de leitura para os menos íntimos, também conhecida no ramo de programação como campo de entrada de dados ou input.


 

Exemplo o abaixo é um sys_read ou chamada de sistema de leitura.


 

mov eax, 3 ; Número da chamada do sistema

mov ebx, 2 ; file descriptor (stdin)

mov ecx, numero ; valor da variável a ser pegada

mov edx, 5 ; Tamanho da mensagem a ser mostrada em bytes

int 80h ; Chamada no kernel


 

Usado quando queremos pegar dados que usuário digitou.


 

Agora disponibilizarei aqui uma pequena tabela com os exemplos que falei e outros mais. Fique à vontade e use sua imaginação para criação de novas chamadas.


 

Nome

eax

ebx

ecx

edx

Sys_exit

1

int

 

 

sys_fork

2

struct pt_regs

 

 

sys_read

3

unsigned int

Char *

Size_t

sys_write

4

unsigned int

Const char *

Size_t

sys_open

5

const char *

int

int

sys_close

6

unsigned int

 

 


 

Na tabela acima de inicial procure focar sua atenção no eax, pois é ele a opção mais importante que temos que trocar para mudamos as chamadas.


 

Veja que no exemplo mostrado na tabela acima os registradores eax, ebx, ecx, edx são de 32 bits.


 


 

Como compilar e linkar um código Assembly para geração de um executável?


 

Atenção: certifique-se o Nasm está instalado primeiro, se estiver instalado siga os passos seguintes:


 

1° Crie um arquivo com o código Assembly utilizando um editor .txt e depois salve-o com a extensão .asm

Ex: programa1.asm

2º Abra o terminal do Linux, na linha de comando e digite:

nasm -f elf32 programa1.asm

Observação: Após utilizar do comando acima, se tudo der certo, será gerado um arquivo programa1.o 

3° Crie o executável com o comando abaixo:

 ld programa1.o -o programa1.x 

 

 3° Para executar, digite:

./programa1.x

Link para o comentário
Compartilhar em outros sites

Legal o conteúdo, Lincoln. ?

O exemplo da sys_read, no entanto, tem alguns errinhos: imagino que você queria ler de stdin e não de stdout. O conteúdo lido vai para o ponteiro em ecx e, por fim, o inteiro em edx define a quantidade de bytes a serem lidos. Corrige aí. ?

Abraço!

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...