quinta-feira, 25 de outubro de 2012


Quando falamos de Assembly (Assembler é o "compilador"), o que te vem a cabeça?
Normalmente a primeira impressão que temos, é de que a linguagem é algo incompreensível e difícil de se entender, realmente! Mas esta série de tutoriais tem o intuito de "desmistificar" a linguagem, dando uma pequena noção sobre ela.

Pré-requisitos

- Saber programar em alto nível. (C++, Java....)
- Ter um compilador C++ (Neste tutorial usarei o C++ Builder, serve para o Dev-C++, Visual C++....)

Porque um compilador C++?

Pra começarmos esta série de tutoriais, é necessário aprender a lógica de como os bits trabalham, então neste caso, usaremos o C++ como a linguagem "mãe", e o Assembly incorporado no código C++. Isso, para termos uma "noção" antes de escrever uma aplicação em Assembly do zero.



Registradores

Os registradores fazem parte do processador, e são "unidades de memória", que tem a finalidade de armazenar bits.
Lembrando que cada processador possui uma linguagem de máquina e de montagem, sendo assim, estarei programando na arquitetura de processadores x86.

EAX -> Registrador acumulador
EBX -> Registrador de base
ECX -> Registrador de Laços/Loops/Contador
EDX -> Registrador de Dados
.......
[A lista acima mostra apenas alguns dos registradores]

Para esta primeira parte do tutorial, vamos usar apenas o registrador EAX, o acumulador, sendo que no decorrer dos tutoriais, vamos saber um pouco mais sobre os outros registradores.

Criando uma aplicação

Para iniciarmos, vamos criar uma nova aplicação de console no C++ Builder. [Visual C++, Dev-C++...]
No C++ Builder, basta clicar em New | Other... | Console Application

O que temos de início é o código gerado pelo C++ Builder:


#pragma hdrstop
#pragma argsused

#include
#include

int _tmain(int argc, _TCHAR* argv[])
{

}


Para incorporar o código Assembly em C++, basta usar o comando __asm.
Todo o código Assembly deve estar aí dentro, ex:

__asm {
        // código assembly aqui
}

Agora vamos entender como é que funciona a movimentação de bits dentro do Assembly.

Suponhamos que temos a variável num1. Como seria atribuir o valor 5, para essa variável em C++?

int num1;
num1 = 5;

Para inicializar uma variável em Assembly, temos que mover esse valor para ela, da mesma forma de movemos o 5 para o num1 em C++.
A sintaxe é a seguinte:

mov num1, 5

Neste caso, o valor 5 foi movido para a variável num1.
Desta forma, podemos inicializar a variável num2 com o número 3.

mov num2, 3

Simples né? Desta forma podemos inicializar quantas variáveis quisermos.

Movendo bits para um registrador

Como vamos utilizar o registrador acumulador, temos que inicializar uma variável e movê-la para o registrador. A sintaxe é a mesma.

mov eax, num1

Como o valor de num1 era 5, então qual o valor que está no registrador eax? 5.
Dessa forma, podemos manipular os bits e os valores entre as variáveis e os registradores.

Somando um registrador

Como já adicionamos o valor da variável ao nosso registrador, vamos inicializar uma outra variável e somar com o num1. Para somar, usamos o comando add.

mov num1, 5       // num1 = 5
mov num2, 3       // num2 = 3
mov eax, num1     // eax = num1
add eax, num2     // eax = eax + num2

Dessa forma, somamos as duas variáveis num1 + num2 e o resultado está armazenado em eax.
Agora basta mover o valor de eax para outra variável para que possamos exibir o resultado com o C++.
Movemos da mesma forma:

mov res, eax

Relembrando o código anterior, esta última instrução move o valor de eax para a variável res.
Então, qual é o valor de res? 8.

Vamos declarar as variáveis no código C++ e compilar nossa aplicação.

int num1, num2, res;

O código inteiro fica da seguinte maneira.


#pragma hdrstop
#pragma argsused

#include
#include

int _tmain(int argc, _TCHAR* argv[])
{
int num1, num2, res;


    __asm {
        mov num1, 5       // num1 = 5
        mov num2, 3       // num2 = 3
        mov eax, num1     // eax = num1
        add eax, num2     // eax = eax + num2
        mov res, eax      // res = eax
    }

    printf("%s%d", "NUM1 + NUM2 = ", res);
    getchar();            // espera uma tecla


}


O resultado que temos é o seguinte:



É recomendável praticar com o comando sub para fazer subtrações.

sub eax, num2     // eax = eax - num2

Na próxima parte do tutorial, falarei sobre as outras operações aritméticas fundamentais e input de dados do usuário. Parte 2

Não se esqueça de que este, é apenas um tutorial explicando apenas simplificadamente . Para saber mais sobre Assembly, assim como os fundamentos da linguagem, é recomendado um bom livro!
Abraços, bons estudos e até a próxima!!!


               
Fundamentos em Programação Assembly


              










80x86 Assembly Language Architeture

0 comentários:

Postar um comentário