Você está na página 1de 4

####################################################################

# Divertindo-se com o assembly. Por que não? v.1.0 #


# Parte I #
# por Leon de Castela #
# lfgs15@terra.com.br #
# 22/12/2009 #
####################################################################

Dedico ao prof. Chico do CESET/UNICAMP, por ter sido chato, embora


competente(qualidade rara), e que sem sua disciplina de arquitetura de
computadores este tutorial provavelmente não existiria.

Primeiras palavras, não muito longas, para não chatear.

Assembly é como Zen budismo, há duas maneiras de aprender, a difícil e a difícil


e quando você acha que está aprendendo, não está. Confesso que assembly é quase
uma experiência espiritual, uma iluminação! Mas, não fiquem desanimados com
minhas palavras; na condição de "iluminado", pretendo fazer tudo facinho facinho
e de maneira não traumática. Nenhum conhecimento oculto é necessário para seguir
adiante(aposente seus livros herméticos), faço aqui o trabalho de Virgílio que
guiou Dante além das portas do inferno. A única coisa necessária aqui é a
vontade de aprender e o que eu não for capaz de explicar aqui, em caso de
dúvidas o email está aí. Como diria o jovem Sherlock Holmes, "The game is
afoot!"

Primeira lição - O que diabos faz um computador?

Um computador transforma sinais eletromagnéticos em algo que possui significado


para alguém. Muitas pessoas não se dão conta do que acontece dentro de um
computador, assim como elas não precisam saber como seus cérebros funcionam para
ler este texto. Bem, algumas pessoas nem sequer sabem que tem um cérebro, no
entanto, isso é uma outra história.

No nível mais baixo de abstração um computador é só um monte de sinais


eletromagnéticos que dizem se algo está magneticamente carregado ou não. Aí o
homem diz que algo está ligado quando é 1 e desligado quando é 0. Note que 1 e 0
não necessariamente são números, mas descrições de estados.

Esses estados podem ser mapeados para números, como 1010 = 10(dez), ou 0010 = 2,
no sistema binário, aliás se você não entende essas conversões, aconselho
abandonar este tutorial e estudar os sistemas binários e hexadecimais, ou
continuar a ler, a escolha é sua.

Note que o estado <0010>, ou <(desligado), (desl), (lig), (deslig)>, quando


representa o número 2 no sistema decimal, está-se a fazer um mapeamento para um
nível mais alto de abstração. Nada impede que <0010> seja mapeado como <bolo de
chocolate>, a escolha é sua.

Mas por que assembly? O assembly é apenas um desses mapeamentos, como veremos, e
nada mais do que isso.

Segunda lição - Nossa Máquina - A CPU.

Tenho duas notícias, uma boa e uma ruim, a boa é que aprenderemos assembly, a
segunda é que não aprenderemos. Por quê? Porque assembly, sendo uma abstração,
só funciona em um determinado tipo de máquina, ou seja, o assembly de uma
máquina de lavar e diferente do de sua televisão. Isso significa que cada
máquina tem sua própria conjunto de <instruções>.

Para aprender assembly, não é necessário ter um chip Intel, AMD; em vez disso,
criarei uma máquina e por sua vez um assembly para ela. Para nossa felicidade
será semelhante a um computador.
Nossa máquina, que chamarei de M1, terá uma CPU. A CPU é responsável pelo
processamento. A estrutura da CPU é a seguinte: ela possui 4 registradores, AX,
BX, CX, DX; cada um deles possui 16 bits. Os registradores são memórias internas
da CPU(Unidade Central de Processamento). Além, disso ela terá alguns
registradores especiais chamados: SP, IP, que serão explicados mais adiante.
Assim fica então a nossa CPU(M1)

+---------------------+
| |
| |
AX-----| |
| |
BX-----| CPU |
| |
CX-----| |-----SP
| |
DX-----| |-----IP
| |
+---------------------+

Terceira lição - Nossa Máquina - A memória.

Você deve-se perguntar, por que deve haver uma memória além dos registradores?
De fato, poder-se-ia ficar apenas com a CPU e fazer todas as operações usando-se
os registradores, no entanto, para certos programas, os registradores não são
suficientes para realizar todas as operações, portanto, adicionarei uma memória
que terá 128 bits, e será ligada à CPU por um BARRAMENTO de 16 bits. O tamanho
do barramento chama-se PALAVRA, ou WORD, e é a quantidade de bits que a CPU pode
processar em cada ciclo. Logo, nossa máquina M1 fica da seguinte forma:

+-----------+ MEMÓRIA
| | barramento(bus) +-----+-------+------+------+-------+
| | ======================= | 16b | 16b | etc | | |
| CPU | 16bits +-----+-------+------+------+-------+
| |
| |
+-----------+

Quarta lição - Nossa Máquina - Entrada e Saída.

Com a adição da memória, posso dizer que nossa máquina pode fazer qualquer
operação que desejamos, o problema é que ela não possui comunicação com o mundo
exterior e podemos providenciar isso facilmente adicionando uma entrada e uma
saída. A entrada e a saída comunicar-se-ão por outro barramento que também têm
16 bits. Aqui está nossa máquina completa:
+------------+ MEMÓRIA
| | ________________________ +----+--- --+----+
AX-----| | _______BARRAMENTO ______ | | ... | |
BX-----| | 16 bits +----+--- --+----+
CX-----| CPU | 128 bits
DX-----| | (16 bytes)
| |----IP
| |----SP
+------------+
|B|
|A|
|R|
|R|
|A|
|M| 16 bits
|E|
|N|
|T|
|O|
| |
Entrada/Saída (teclado, impressora, monitor, seu cérebro...etc.)

Este é o maravilhoso hardware que construímos, mas para que serve isso tudo??

Quinta lição - Dando ânimo à coisa -- instruções e software.

Não tive o trabalho de construir tal máquina se ela não servisse para nada, na
verdade, do jeito que está não serve para muita coisa mesmo, logo, precisamos de
um espírito, uma <anima>, como diria Aristóteles. Embora isso esteja longe de
uma verdadeira mente, é um modelo interessante. Mas o que isso vai fazer? Bolos,
torradas, sucos? Bem que poderia mas para isso não seria necessário tanto
trabalho bastaria ter como entrada, <laranjas>, mandá-las à CPU e retorná-las à
saída, <suco>. Em vez disso, vamos atribuir duas INSTRUÇÕES à nossa máquina
<add> e <sub>. O que elas fazem? Simples, elas adicionam e subtraem uma unidade
de um registrador. Assim se no registrador AX temos 1, se dermos a instrução:
add AX, AX será igual a 2, ou ser dermos: sub AX, AX será igual à 0. Nada muito
especial, bem, porém, e se quisermos carregar um registrador, o que fazer? Basta
fazer: AX, 15, e AX será igual a 15.

Até agora nada de especial, mas e se quisessemos mandar alguma coisa à CPU
através do barramento. A CPU comunica-se com o "mundo externo" a partir das
INTERRUPÇÕES. Note que, "mundo externo", não é somente o teclado, ou o monitor,
ele pode ser também outros componentes do hardware, exceto a memória é claro,
cuja comunicação é direta, pelo barramento de endereços.

Como nossa máquina é simples o bastante, nossa comunicação terá apenas a


instrução <<int>, <valor>> , para entrada e <out> para saída. Assim se eu quiser
mandar algo para CPU, como o número 12, por exemplo, farei: int, 12 e o número
12 será carregado no registrador AX e somente nele. Se quisermos "ouvir" o que a
CPU tem a dizer, damos um: out; e ela manda para nós o que está no registrador
AX e somente nele.

Agora acho que podemos fazer um pequeno programa de demonstração em nossa


máquina. O programa é simples, ele recebe dois números do usuário e devolve a
soma. Vamos ao código:
; PROGRAMA 1 - SOMA DE DOIS NÚMEROS
int, 7h ;carrega o número da entrada no registrador AX
BX, AX ;salva o número de AX em BX
int, 4h ;carrega o número da entrada no registrador AX
CX, AX ;salva o número de AX em CX
SOMA:sub CX ;decrementa o conteúdo de CX por 1
add BX ;incrementa o conteúdo de BX por 1
jz SOMA ;pula para SOMA se CX for 0
AX, BX ;põe o resultado em AX
out ;imprime o resultado em qualquer lugar que você imagine

Ho! Se não fiz alguma besteira... deve funcionar. Coisas novas! Por exemplo, o
que é JZ?, JZ(Jump If Zero) é uma espécie de "estrutura de decisão", que pula
para o LABEL: e repete o código. Eu acho que o código fala por si, e que meus
comentários são suficientes para esclarecer o que acontece. Há algo proposital,
CX é o contador do código e é o que acontece nos X86 também. Bem estou meio
cansado e tenho que parar por aqui, encontramo-nos na segunda parte e deixo
algumas outras instruções.

Operações Jump:

JZ - Pula se CX for zero


JMP - Pula sempre
JNZ - Pula se CX não for zero

Com essas instruções pode-se calcular o que quiser, caso não acreditem
verifiquem uma linguagem de programação chamada <<brainfuck>>. É isso, na
próxima parte, falaremos de memória, ponteiros, pilha... bons sonhos ou vá
tomar um sorvete com café!