#################################################################### # 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: +-----------+ | | barramento(bus) | | ======================= | CPU | 16bits | | | | +-----------+ MEMÓRIA +-----+-------+------+------+-------+ | 16b | 16b | etc | | | +-----+-------+------+------+-------+

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é!

Sign up to vote on this title
UsefulNot useful