Вы находитесь на странице: 1из 22

Índice do Curso Assembly Progressivo

Parabéns por optar por estudar essa bela linguagem de programação.


Estudar Assembly é estudar o real funcionamento de um computador, é ter total controle e visão do
que ocorre em sua máquina.

Assembly não é difícil, pelo contrário, é, de longe, a linguagem mais simples existente.
Poucos comandos são necessários para programar em Assembly, diferente de dezenas de funções,
classes, API e opções existentes nos frameworks das linguagens de alto nível.

Aliás, para programar em Assembly não é necessário nenhum software ou programa.


Você pode criar tudo diretamente de qualquer editor de textos.

Mesmo que não seja um Engenheiro de Elétrico, Eletrônico, de Computação ou um programador


profissional de Assembly, estudar essa linguagem fará com que você cresça como profissional, pois
você vai entender absolutamente tudo que ocorre os bits dentro de sua máquina.

Desejamos um bom estudo aos leitores do curso Assembly Progressivo.

Introdução ao estudo do Assembly x86


00. Níveis de abstração em um computador: onde está o Assembly ?
01. Como começar a programar em Assembly
02. Assembly é a melhor linguagem de programação ?
03. As desvantagens e dificuldades: quando não usar Assembly
04. As vantagens e benefícios: quando se deve usar Assembly

O básico da linguagem Assembly


00. O necessário para programar em Assembly: como instalar o Assembler NASM no Windows
01. O necessário para programar em Assembly: como instalar o Assembler NASM no Linux
02. Como fazer o Hello World (Oi mundo) em Assembly
03. Como criar object files(código objeto) e linkar arquivos em Assembly
04. Sections e _start: A divisão do código-fonte Assembly - A diretiva global
05. Labels: o que são, para que servem e como usar - Labels internos (local label)
06. Como alocar e reservar espaços de memória - As diretivas DEFINE e RES
07. Vetores e Arrays em Assembly - A diretiva TIMES

Onde o Assembly age: Níveis de abstração na Computação


Para entender um pouco mais de Assembly, precisamos explanar os diversos níveis de abstração que
um computador possui. Dentro dessa ordem de níveis, o Assembly se encontra mais abaixo, mais
próximo do hardware, por isso é dito ser uma linguagem de baixo nível.

Para entender melhor, vamos começar de cima, de onde você provavelmente deve estar agora, ao ler
esse tutorial de Assembly.

A camada dos softwares e aplicações de alto nível


Aqui é onde está a maioria dos usuários de computadores, tipicamente lidando com aplicações
gráficas, clicando em botões, menus, minimizando, maximizando, fechando janelas, navegando na
web e outras infinidades de coisas.
Nesse estágio, as coisas são bem simples e voltadas para o usuário leigo.
Não é necessário saber absolutamente nada sobre o funcionamento interno dos sistemas. E, de fato,
a grande maioria dos usuários não sabe.

Para o usuário, é tudo a mesma coisa, não importa se ele esteja no Windows, MacOS, Linux,
Android ou TV Digital: ele quer ver menus, botões, clicar, arrastar, fechar e o mesmo de sempre.
Uma mera tela preta, como a do MS-DOS ou Terminal do Linux, já seria motivo de espanto e
repúdio. Nesse estágio, as coisas são voltadas para o agrado desse tipo de usuário, que mesmo sendo
totalmente leigos, são os que sustentam o ramo da computação.

E realmente, a grande maioria das pessoas não tem motivos para entender o que se passa por
debaixo dos panos dessas aplicações: são médicos, advogados, professores exibindo slides nas aulas,
caixas de supermercado e praticamente todo tipo de profissional vai ter contato com essa camada.

A camada das linguagens de alto nível


Quando pensamos em programar, geralmente pensamos em criar um super jogo, um programa bem
útil ou aplicação móbile. Pensamos em criar algo para a camada de softwares de alto nível, pois é o
que mais estamos acostumados a lidar.

Para fazer programas desse tipo, de alto nível, usamos linguagens de programação de alto nível,
como Java, linguagem C, C++, C#, Python, Pascal, Delphi, Visual Basic, JavaScript, PHP e outras
linguagens famosas.

Os programados dessas linguagens são capazes de criar entender como funcionam os softwares de
alto nível em um nível não muito profundo, pois não é necessário entender muito do funcionamento
dos sistemas operacionais.

Na linguagem de programação Java, por exemplo, você nem precisa se importar com o sistema, pois
é uma linguagem multi-plataforma, ou seja, uma aplicação feita em Java pode rodar em Windows,
Linux, Mac, celulares etc, com poucas ou nenhuma alterações.

Essas duas camadas de abstração são, portanto, independente da arquitetura do sistema.


Um programador Java, por exemplo, não precisa saber qual o processador da máquina que vai
programar, e nem como funciona a arquitetura de seu sistema. São níveis de abstração que não
dependem do sistema.

Camada da linguagem Assembly


Essa camada é o objetivo de nossa apostila de Assembly, e diferente das outras linguagens,
precisamos saber que tipo de arquitetura vamos trabalhar.

Isso porque os comandos e códigos que vamos usar na linguagem Assembly são diferentes e
específicos para cada tipo de processador. Ou seja, o nível de abstração da camada da linguagem
Assembly é dependente do sistema.
É tão dependente que até precisamos saber como é organizada e o funcionamento da memória da
máquina onde vamos programar.

Por isso não existem cursos para todos os tipos de Assembly, a linguagem varia de acordo com cada
máquina. Diferente da linguagem Java ou C++, que não importa o tipo de computador para
programar.

Por estar abaixo das aplicações gráficas, das linguagens que criam essas aplicações e ser dependendo
do sistema, a linguagem de programação Assembly é dita de baixo nível.
A camada do código de máquina
Você já deve ter ouvido falar que tudo, absolutamente tudo, em computação, é feito de números 1 e
0. E isso é verdade.
O computador (no sentido bem baixo da palavra, ou seja, o metal, as peças eletrônicas) só entende e
obedece a esses comandos, que nada mais são que uma série de números binários (1’s e 0’s). Porém,
quantas vezes você já programou ou ouviu falar de alguém que programa em binário?

O objetivo da linguagem Assembly é suprir esse problema da alta complexidade do binário.


Com o Assembly escrevemos de uma maneira mais ‘humana’, mais fácil e compreensível, e esse
código é convertido para o código de máquina.

Esse é o limite dos programadores. Porém, há muito, mas muito mais abaixo do Assembly, que
envolvem coisas de elétrica e eletrônica digital (latches, flip-flops, transistores, circuitos integrados
etc). Quem se interessar por esse meio, poderá adquirir conhecimentos através de cursos como
Engenharia de Computação, Engenharia Elétrica, Engenharia Eletrônica e cursos do gênero.

Como começar a programar em Assembly


Conforme foi explicado no tutorial passado, sobre os níveis de abstração da programação na
computação, existem vários tipos de Assembly pois essa linguagem trabalha diretamente no
hardware, e como você sabe, existem diversos tipos de hardwares (processadores, para sermos mais
específicos).

Portanto, é necessário que seja feita algumas escolhas.


Vamos escolher as mais comuns, abrangentes e de fácil acesso possível.

Arquitetura usada: IA-32 (Intel Architecture 32-bit)


Vamos ensinar a linguagem Assembly para processadores da Intel.
Embora os de 64 bits sejam os que estão crescendo e ocupando seu lugar no mercado, para iniciar,
ainda é mais indicado os estudos pelos processadores de 32 bits.
Aqui você encontra uma lista de processadores da Intel:
http://en.wikipedia.org/wiki/List_of_Intel_microprocessors

Embora a tecnologia tenha avançado bastante, os conjuntos de instruções não mudaram a ponto de
ser necessário um novo aprendizado. Embora os primeiros microprocessadores da Intel de 32 bits,
tenham quase 30 anos, seu ‘jeitão’ continua o mesmo, e amplamente usado.
O que vêm mudando é capacidade e velocidade de processamento dos mesmos.

“E se meu processador for diferente?”


É quase impossível não ter acesso a um computador com processador Intel hoje em dia, mas se você
não tiver, deve ou estudar por um material mais específico para sua máquina ou estudar para os
processadores da Intel, pois embora seja diferente, a linguagem Assembly difere nos detalhes, sendo
possível o aprendizado da linguagem.

Esse tipo de arquitetura também foi implementada em processadores da AMD, por exemplo.
Esses conjuntos de instruções de diversos processadores diferentes obedecem a um conjunto de
instruções da mesma arquitetura, que são conhecidos como x86-32, i386 ou simplesmente x86
(subtende-se que se trata de 32 bits, pois os processadores de 16 bits estão em desuso).

Assembler: mnemônicos e opcode (operation code)


Como já dissemos, os computadores em si só ‘entendem’ e obedecem uma série de comandos
representados por números 0 e 1.
Obviamente, poderíamos escrever 0’s e 1’s diretamente para nossas máquinas, mas o trabalho e as
chances disso dar errado são gigantescas.

Por isso, é comum trabalharmos com números hexadecimais em Assembly (base numérica de 16
elementos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E e F). Porém, embora ajude bastante, ainda é algo
extremamente enfadonho.

Para superar essas barreiras, a linguagem de Assembly possui palavras reservados chamada
mnemônicos, que servem para o humano programar com maior facilidade, sem ter que usar números
o tempo inteiro.

Por exemplo, até mesmo linguagem C podemos trabalhar com endereços de memória.
Mas endereços são números (e geralmente grandes), então para evitar decorar e escrever números,
damos nomes as nossas variáveis e passamos a tratar elas por esse nome, e não pelo seu endereço.

Então, o mnemônico é um nome que usamos para substituir diversos comandos, é como se fosse um
atalho: estamos escrevendo com nomes diferentes, mas a ação é a mesma, pois é mais fácil tratar
uma pessoa pelo seu nome do que com seu número do RG.

Mas existe uma diferença entre o Assembly e as demais linguagens: em Assembly, tudo é binário,
inclusive as operações com os dados.
Podemos somar um número a outro usando apenas números binários que representam as etapas da
soma. Obviamente isso é extremamente trabalhoso, e vamos usar o mnemônico add ao invés de
números, para tratar operações de adição.
Por exemplo, a instrução hexadecimal dessa operação é: 83060F000A

Ou seja, com os mnemônicos vamos dar nomes as operações, dados e instruções, ao invés de
trabalhar com os opcodes, que são instruções diretas de máquinas.

Ou seja, escrevemos na forma ‘humana’(nomes) e ela é transformada em forma de máquina


(binários), e quem faz isso é um programa chamado Assembler.
O Assembler vai transformar cada instrução feita na linguagem Assembly para a linguagem de
máquina.

Existem diversos tipos de Assemblers no mercado, mas vamos usar o NASM (Netwide Assembler),
pois ele é gratuito, atualizado e está disponível tanto para as plataformas Linux como para Windows.

Para mais informações sobre como baixar o NASM, acesse seu site oficial e instale o NASM para
seu sistema, para que possa prosseguir com nosso curso de Assembly: http://www.nasm.us/

Assembly é a melhor linguagem de programação?


É comum vermos na internet, principalmente em fóruns, pessoas falando que linguagem X é melhor
que Y, que Y paga melhor que a linguagem Z, que linguagem isso é mais ‘foda’ que linguagem
aquela.

Ignore, totalmente, esses tipos de comentários e pessoas.


Não existe melhor linguagem, existem linguagens e tecnologias mais indicadas para cada tipo de
problema.

Qual é a melhor linguagem de programação?


Vamos traçar um paralelo, com veículos de locomoção.

Um avião é bem mais veloz que um carro, óbvio não?


Além disso, é mais eficiente e seguro. Mas isso vai exigir um custo (financeiro, burocrático, estudo
etc) bem maior.
Devemos usar, então, o avião para viajar? Depende da viagem.

Já um carro é bem mais barato e não é tão caro pra manter quanto um avião.
Mas é bem mais lento, perigoso e menos eficiente.
Mas é fácil de dirigir um, e não precisa de muito estudo, apenas temos que tirar a carteira de
habilitação.
Ora, se é mais barato e prático, devemos usar carros para viajar? Depende da viagem.

Já uma bicicleta é bem, mas bem, mais barata. Não precisa gastar dinheiro para usá-la, nem é
necessário ter uma idade mínima, habilitação ou sequer idade mínima para se deslocar numa bike.
Ora, se é praticamente de graça viajar em uma bicicleta, devemos usá-la para viajar?
Depende da viagem.

Tenho certeza que você entendeu os dependes dos exemplos anteriores, bem como tem bom senso
suficiente para saber quando usar um ou outro.
Para viagens longas entre lugares distantes, avião sem dúvidas é a melhor opção.
Para ir a outra cidade, ou viajar para o interior ou literal, é mais cômodo ir de carro.
Já para ir pra escola ou andar alguns quarteirões, a bicicleta é a melhor alternativa.

Então, qual desses veículos é o melhor?


A resposta é: não existe melhor, existe solução mais adequada para cada tipo de situação.

Com esse exemplo, é bem fácil entender, mas geralmente as pessoas não levam isso para o mundo da
programação, e nesse âmbito a situação é a mesma: você tem que ver seu problema e analisar qual a
melhor solução para ele
.No caso, qual melhor linguagem, tecnologia e o melhor meio para abordar tal problema.
Portanto, dizer que linguagem A ou B é melhor, é dar um atestado de sua ignorância e estará
carimbando seu documento de leigo poser.

Porém, a linguagem Assembly é bastante respeitada e considerada por muitos como a melhor,
principalmente por engenheiros, escovadores de bits (pessoas que amam computação, e querem
saber tudo que ocorre, nos mínimos detalhes, em suas máquinas) e por hackers.

No próximo artigo de Assembly entraremos em detalhes sobre as vantagens dessa linguagem, bem
como suas desvantagens.
Sim, como todas as linguagens, há desvantagens em usar o Assembly. Não se iluda.

As desvantagens e dificuldades do Assembly


Agora que você já leu sobre ‘A melhor linguagem de programação’, e sabe da santa verdade, vamos
entrar em detalhes sobre o uso do Assembly.

Nesse artigo vamos discutir as as desvantagens da linguagem.


Vamos mostrar os problemas de se programar nessa linguagem e que vão pesar na hora de você
decidir que tecnologia deve usar para seu sistema.

Quando não se deve usar Assembly


Embora seja uma poderosa e importantíssima linguagem, louvar e querer usar sempre o Assembly,
para qualquer tarefa, é algo totalmente inviável.
Para deixarmos o leitor da apostila Assembly Progressivo informado e realista, vamos começar
falando das desvantagens dessa linguagem de programação.
Complexidade dos programas em Assembly
Não vamos mentir nem tentar esconder nada: Assembly é a linguagem mais difícil sim.
Não é tão óbvia e simples de se aprender, como Python ou Visual Basic.
Isso não quer dizer que é impossível de se programar em Assembly, só quer dizer que você terá que
se dedicar mais ao estudo da linguagem.

Configurações específicas para programar em Assembly


A grande diferença, ou sacada, da linguagem Java é que é multi-plataforma.
Ou seja, criando um programa em Windows, ele rodará num sistema Linux ou MacOS, não
importando a arquitetura de seu computador.
Aliás, não precisa nem ser computador, várias outras linguagens rodam dispositivos móveis, tablets,
TV Digital etc.

Como explicamos no artigo sobre Como Programar emAssembly, precisamos programar


especificamente para cada tipo de arquitetura, pois há diferenças nos tipos de Assembly.
Logo, Assembly não é portável. Você não pode criar um programa em Assembly e garantir que ele vá
rodar em outros sistemas.

Essa é uma das grandes vantagens de programação voltadas para web, como PHP, JavaScript e a
linguagem de marcação HTML, elas só dependem do navegador, não dependem do sistema
operacional, muito menos de um tipo específico de processador, como precisa as variáveis do
Assembly.

Baixa produtividade do programador Assembly


Quem é iniciante ou programa por hobbie, provavelmente nunca se preocupou com produtividade.
Mas quem trabalha e depende disso como meio de vida, sabe que não basta usar bem uma linguagem
de programação ou saber muito de computação: você terá chefe e prazos.

As vezes deixamos de lado uma linguagem poderosa e eficiente (como Assembly, C ou C++) e
optamos por uma mais lenta e menos poderosa, como Java ou C# simplesmente porque precisamos
ser produtivos, ou seja, precisamos produzir mais em menos tempo.

Uma aplicação que você faz em algumas horas em Java, Python ou Perl, levaria semanas ou meses
para fazer em Assembly. Os códigos em Assembly são longos, cheios de detalhes e pormenores, o
programador fica a cargo de tudo.

Assembly é uma linguagem crua e com poucos ‘recursos’


Não importa qual seja o programa que vá criar, para uma empresa, loja ou um jogo, boa parte do
que você precisa já está feito em Java ou C#, na forma de API’s e Frameworks, que são recursos
prontos que você pode usar em suas aplicações.

Já em Assembly as coisas não vêm prontas, não há uma infinidade de bibliotecas, funções e recursos
feitos e prontos do jeito, e do tanto, que as linguagens de alto nível. Logo, é necessário criar mais
códigos e programas para fazer algo nessa linguagem.

Difícil manutenção de código Assembly


Os iniciantes talvez não vão entender bem isso, mas em empresas, não basta apenas escrever o
código para o programa funcionar. Códigos fonte sempre são alterados com o tempo.
Por isso é importante fazer um código ‘legível’, de fácil entendimento, comentado e documentado
para que outras pessoas (ou você no futuro) possam ler e entender depois.
Como os códigos em Assembly geralmente são grandes, não são tão óbvios e fáceis de entender (em
algumas linguagens, como Python, basta passar o olho no código para entender o que está
ocorrendo). Portanto, códigos em Assembly costumam dar trabalho para se fazer a manutenção.

As vantagens e benefícios do Assembly


gora que você já leu sobre as desvantagens e dificuldades da linguagem Assembly, vamos falar sobre
onde essa linguagem é usada e seus benefícios.

Assembly é eficiente
Se você mandar duas pessoas, equipes ou empresas, fazerem os mesmos softwares, verá que é
impossível o código delas serem iguais. Programar é raciocinar, é criatividade, depende do intelecto,
experiência e raciocínio dos programadores e chefes.
É por isso que existem navegadores Web bons e ruins, Sistemas Operacionais lentos e rápidos, jogos
bem feitos e mal feitos etc.

Isso tudo é eficiência: fazer um programa que rode mais rápido, que consuma pouco processamento
ou que exija o mínimo de memória possível. E isso o Assembly é único.
Um programa bem feito em Assembly é simplesmente imbatível.

Sim, é trabalhoso.
Sim, é demorado.
Sim, é, algumas vezes, entediante. Mas uma vez feito, e bem feito, você terá feito um ótimo trabalho
e poderá ter a certeza que vai tirar o máximo de sua máquina.

Não é à toa que é Assembly é uma linguagem muito usada em situações críticas, como em alguns
trechos da construção de sistemas operacionais, como o Linux (em sua grande parte é feito em C,
mas em algumas partes é necessário usar Assembly).

Assembly é rápido
O gerenciamento de memória na linguagem Java, por exemplo, é feito de forma automática.
A vantagem disso é que o programador não precisa lidar com ponteiros, endereços de memória,
alocação e liberação de memória (o que é considerado por muitos como as coisas mais difíceis em
programação).
A desvantagem é que isso não é perfeito, e não passa nem perto de ser algo 100% eficiente.

Em Assembly não existe nada automático assim, é você programador que vai mandar e controlar
tudo. E isso é essencial, ter o controle de tudo, quando é necessário funcionamento máximo, como
em microcontroladores e sistemas eletrônicos (imagina um sistema lento em uma aeronave? Não dá,
em questões e sistemas de segurança, precisamos de processamento máximo).

Assembly exige menos memória


Por dar total acesso e uso de cada espaço de memória ao programador, o Assembly permite que as
aplicações feitas nessa linguagem possam ocupar e usar o mínimo de memória possível.

“Com tantos computadores poderosos de gigas e gigas de memória e processamento, por quê se
preocupar com o tanto de memória utilizada?” pode se perguntar o leitor e programador de
linguagens de alto nível.

A linguagem de Assembly não é somente para computadores.


Existem microcontroladores com meros kilobytes de memória, em que não é possível fazer nem um
“Hello world” em diversas outras linguagens de programação, e só é possível programar neles, e em
outros dispositivos digitais, com Assembly.

Do ponto de vista prático, nenhum empresário vai gastar Megas de memória em simples circuitos,
como de calculadores, freezer e outros sistemas digitais, quando se pode gastar apenas poucos Kb
usando a linguagem Assembly.
Se assembly usa menos memória, mais barato irá sair o projeto. Isso não é importante, é essencial
para todos os engenheiros.
Ser eficiente só na teoria não adianta, tem que ser eficiente e economicamente viável.

Assembly dá acesso direto ao hardware


Nem todo equipamento é bonitinho e perfeito para se trabalhar como um computador.
Existem dispositivos sem teclado, sem tela, com tipos diferentes de memória, de processador e com
arquiteturas e funcionamentos diferentes. Obviamente, a grande maioria das outras linguagens de
programação não seriam nem cogitadas para se usar nesses sistemas.

Embora hoje em dia os vídeo-games sejam tão potentes quanto os computadores, eles não são feitos
da mesma maneira que os PC's e Notebooks. Eles não tem as mesmas peças, acessórios e recursos
que facilitam a programação neles.
Ou seja, em alguns casos, SÓ É POSSÍVEL DE SE TRABALHAR COM ASSEMBLY.
Em décadas passadas, não só o hardware dos vídeo games eram controlador por mas os jogos eram
feitos inteiramente com o uso da linguagem Assembly.

Os programas em Assembly são menores


Embora os códigos tendam a ser bem maiores que os das outras linguagens, depois de pronto, os
aplicativos em Assembly são bem menores em tamanho.

Isso se deve ao fato do programa em Assembly ser muito eficiente e consumir pouca memória.
Além de não ter outras aplicações atuando por debaixo dos panos, como acontece em outras
linguagens.

Segurança no Assembly: uma faca de dois gumes


Esse tópico pode ser tanto uma vantagem como uma desvantagem.

Sistemas feitos em linguagens de alto nível são freqüentemente burlados por hackers, pois as
aplicações que fazem uso de tais linguagens não mostram nem oferecem tudo aos programadores. A
gigantesca maioria desses profissionais não sabe ao que está ocorrendo em baixo nível.
E mesmo que soubessem, a maioria das linguagens simplesmente não oferece a possibilidade de se
trabalhar próximo ao hardware.

Como um aplicativo em Assembly age nos mais baixos e fundamentais níveis, um programa bem
feito nessa linguagem é bem mais seguro em outras linguagens, pois você pode programar e
controlar manualmente cada detalhe do sistema, e de sua máquina.

Porém, como dissemos anteriormente, códigos em Assembly são grandes e complexos.


Á medida que as aplicações e sistemas forem ficando maiores, o controle sobre tudo vai ficando cada
vez menor.

Ou seja, um bom programador Assembly pode prover segurança e controle que nenhum outro pode
ter. Porém, ele também pode abrir brechas que outras linguagens não abririam.
Fica óbvio o motivo de vários aplicativos de cunho hacker e cracker usarem Assembly.

Assembly serve para aprender como as coisas funcionam


Há pessoas que estudam não por serem obrigadas, por estarem na faculdade ou por ser necessário
para ganhar dinheiro em sua profissão.
Há pessoas que simplesmente gostam de estudar, seja por paixão, hobbie ou tédio.

A definição correta de hacker é daquele indivíduo que quer saber como e porque as coisas
funcionam. Costuma-se chamar escovador de bits aquele que é curioso, tem interesse em saber e
mexer nos computadores em níveis mais fundamentais possíveis.

Não importa se programa em C, Java, .NET ou até mesmo para Web, saber Assembly vai te dar uma
noção de como as coisas realmente funcionam, vai abrir sua mente, melhorar seu raciocínio e
compreensão sobre computadores e dispositivos digitais, deixando você, por natureza, diferenciado
dos outros profissionais que simplesmente usam as tecnologias, sem saber o que está ocorrendo
debaixo de seu nariz.

“Não sou louco em querer entender como funciona um carro. Louco é quem senta em cima de
toneladas de ferro que possuem a força de centenas de cavalos, sem saber o que está acontecendo
logo abaixo.”
Como programar em Assembly no Windows – Instalando o
Assembler NASM
Para começarmos a programar na linguagem de programação Assembly, precisamos de um
programando chamado Assembler, que irá converter nosso código para um código que a máquina irá
entender.

Vamos usar o NASM (NetWide Assembler), que pode ser usado no Windows ou no Linux.
Nesse tutorial de nosso curso de Assembly, vamos ensinar como instalar esse Assembler no sistema
operacional Windows.

Diferente do que os usuários de Windows devem estar acostumados, a utilização desse programa se
dará pelo terminal de comando, o MS-DOS (sim, aquela tela preta).

Baixando o NASM
Para baixar o NASM vá na página oficial do Netwide Assembler:
http://www.nasm.us

Como o projeto continua se desenvolvendo, não podemos especificar uma versão, pois no momento
que você estiver lendo esse tutorial de Assembly a versão oficial do NASM pode ser diferente da
versão usada pelo Assembly Progressivo.

Portanto, ao entrar no website, clique na seção de Downloads, e em seguida abra o diretório da


versão mais recente.
Lá você verá um vários diretórios com nome dos mais diversos sistemas operacionais, neste tutorial
vamos ensinar a instalação no Windows.

Como instalar o NASM no Windows


Se estiver usando Windows, escolha o diretório Win32, e dentro dele baixe diretamente o executável
ou arquivo zipado.

No arquivo zipado, você deve descompactar o arquivo e colocar o nasm.exe e outros arquivos/pasta
no diretório de seu sistema (geralmente é a pasta C:\Windows\System32), pois o NASM precisa
estar no path do DOS (digite path no cmd.exe e veja seu path).

Para checar se você instalou corretamente o NASM, vá no menu iniciar e digite cmd, e abra o
cmd.exe.
Uma tela do MS-DOS deverá abrir. Digite o seguinte comando:
nasm –h

É o comando de help, ou seja, para pedir ajuda ao NASM.


Caso apareça uma avalanche de texto, é porque está tudo ok com seu Assembler.
Pronto, somente isso é o necessário para começar a programar em Assembly.

Como programar em Assembly no Linux – Instalando o


Assembler NASM
ara começarmos a programar na linguagem de programação Assembly, precisamos de um
programando chamado Assembler, que irá converter nosso código para um código que a máquina irá
entender.

Vamos usar o NASM (NetWide Assembler), que pode ser usado no Windows ou no Linux.
Nesse tutorial de nosso curso de Assembly, vamos ensinar como instalar esse Assembler no sistema
operacional Linux.

Para programar em Assembly, iremos usar corriqueiramente o terminal do Linux, tanto na instalação
como na montagem de nossos códigos-fonte, para criar os programas.

Baixando o NASM
Para baixar o NASM vá na página oficial do Netwide Assembler:
http://www.nasm.us

Como o projeto continua se desenvolvendo, não podemos especificar uma versão, pois no momento
que você estiver lendo esse tutorial de Assembly a versão oficial do NASM pode ser diferente da
versão usada pelo Assembly Progressivo.

Portanto, ao entrar no website, clique na seção de Downloads, e em seguida abra o diretório da


versão mais recente.
Lá você verá um vários diretórios com nome dos mais diversos sistemas operacionais.
Aqui iremos baixar, descompactar e utilizar o NASM para GNU/Linux.

Como instalar o NASM no Linux


Dentro da seção de Downloads você encontrará os arquivos para instalação no Linux, eles estão no
formato nasm-xxx.tar.yy, onde xxx é a versão, e yy a extensão compactada.
Os arquivos nasm-xxx-xdoc.tar.yy se referem a documentação oficial do Assembler NASM.

Já dentro do diretório linux/ você encontrará os arquivos rpm para instalar em distribuições Linux do
tipo Red Hat, como o Fedora.

Após baixar e descompactar, pelo Terminal vá na pasta do NASM e rode o script para configurar a
instalação, com o seguinte comando:
./configure

Para construir, digite o comando:


make

Após terminar o make, para instalar o NASM digite:


make install

E seu Assembler estará instalado em seu sistema operacional Linux.

PS: caso ocorra erros em sua instalação, efetue-a como super usuário, ou através do comando sudo
antes de cada comando.

Primeiro programa em Assembly - Como fazer o Hello World


(Olá Mundo)
Agora que você já sabe instalar o NASM, vamos ensinar como criar seu programa em Assembly.

É um texto com o código em Assembly para você ir se familiarizando.


Tenha em mente que este é apenas o primeiro passo para programar nessa linguagem.
Nos próximos tutoriais vamos ensinar os procedimentos para executar um programa em
Assembly, bem como explicar detalhadamente o significado de cada comando nessa verdadeira sopa
de letrinhas.

Não se assuste, em breve você entenderá tudo perfeitamente e dominará esse bela e poderosa
linguagem de programação.

Código do Hello World em Assembly


Crie um arquivo de texto com o nome "hello.asm" e escreve o seguinte código dentro dele:

section .data
msg db 'Como programar em Assembly - Curso Assembly
Progressivo', 0AH
len equ $-msg

section .text
global _start
_start: mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 80h

mov ebx, 0
mov eax, 1
int 80h

Sim, todas essas linhas de código são para exibir a mensagem "Como programar em Assembly -
Curso Assembly Progressivo".
Esse, porém é um código 'humano', pois usamos mnemônicos, que são símbolos e códigos para que
nós possamos entender.
Obviamente, os computadores não leem como as pessoas, eles simplesmente obedece aos comandos
em binários.

E é isso que vamos ensinar no próximo tutorial, sobre como criar os object files (código objeto) e
linkar arquivos em Assembly, nós vamos ensinar como transformar esse código humano em código
binário.
Vamos montar (e não compilar) tal código, que é o que seu computador realmente vai entender e
obedecer.

O código de máquina será o código objeto, que são arquivos com extensão .o
Em seguida, o próximo passo é reunir todos esses object files, bem como códigos que usamos de
outras bibliotecas, e criar um executável. Ou seja, vamos linkar, agrupar tudo que é necessário para
rodar o programa.

Como criar object files (código objeto) e linkar arquivos em


Assembly
No tutorial passado de nossa apostila, ensinamos como criar um programa em Assembly, o famoso e
simples "Hello world".

Lá, mostramos como criar o arquivo com a extensão asm.


Ao término deste tutorial, você irá aprender como transformar esse arquivo em executável, e
executá-lo.

Como transformar um arquivo .asm em executável


Agora precisamos converter nosso código em Assembly, que é feito e entendido por nós humanos,
para a linguagem de máquina, que é a linguagem que o computador realmente entende e roda.

Isso se faz em dois passos:


• Criar o object file, que pega o .asm e cria, a partir dele, um arquivo com a extensão .o
• Linkar nosso programa, fazendo com que o código-objeto se torne em um executável
Vamos ensinar como fazer isso utilizando o assembler NASM, no sistema operacional Linux.
Um importante detalhe: dependendo da arquitetura de seu sistema, 32 bits ou 64 bits, os comandos
diferem um pouco, mas ensinaremos como trabalhar em ambos casos.

Como criar o object file em Assembly


Agora vamos criar o arquivo com extensão .o, que é o objeto (resultado da transformação do código
para código de máquina).

Para isso, vamos finalmente usar o nasm.


Como Assembly é baixo níveo, o código vai se diferenciar levemente caso você use 32 ou 64 bits,
mas nosso tutorial de Assembly vai explicar você a rodar seus programas em ambas arquiteturas.

Caso seja 32 bits, vá no diretório do hello.asm e digite o seguinte código no terminal:


nasm -f hello.asm

Caso seja 64 bits, digite:


nasm -f elf64 hello.asm
Se você notar bem, foi criado um arquivo com extensão .o, é o arquivo-objeto hello.o

Como linkar arquivos em Assembly


O próximo passo é a linkagem, onde vamos transformar o(s) códigos objeto de nossos programas
para torná-los executáveis.
Vamos usar o comando ld para isso.

32 ou 64 bits:
ld hello.o -o hello

Pronto, agora você tem seu arquivo executável "hello". Para rodá-lo, digite o comando a seguir, que
deve mostrar uma mensagem na tela:
./hello

---------------------------------------------------------------------------------------------
Uma outra maneira de fazer todo esse processo é a seguinte:

1. Criar o código-objeto:
nasm -f hello.asm

2. Linkando
32 bits:
ld hello.o -o hello

64 bits:
ld -m elf_i386 hello.o -o hello

Sections e _start: A divisão do código-fonte Assembly - A


diretiva global
Quando um executável vai rodar, ele precisa saber a partir de onde, no código, ele começa a rodar.

Em programação, começar do começo não é algo comum.


Tendo em vista esses dados sobre a informação da ordem das coisas em um código, vamos falar
neste tutorial de Assembly sobre as seções (sections) de um arquivo-fonte em Assembly.

Deixando seu código organizado


Programas feitos na linguagem de baixo nível Assembly tem uma características em comum: eles são
grandes.

Sim, programar em Assembly é escrever bastante, pois é uma linguagem totalmente crua, onde muito
pouco 'existe' e muito, quase tudo, é necessário criar.
Para se fazer um simples programa de cálculos matemáticos simples (somar, subtrair etc) é
necessário que fazer uma rotina, manualmente, para essa tarefa, usando somente as instruções
nativas do processador.

Em linguagens de alto nível, como C e Java, isso já vem totalmente pronto.


Não é necessário criar nada, somente utilizar.
Então, mais que todas as outras linguagens, é necessário ter organização para programar em
Assembly. Seu código deve ser legível, organizado e comentado.

Visando essa organização, existe um comando (ou simplesmente rótulo, ou marcador) chamado
section, que serve para definirmos seções em nosso código.
Para declarar uma section fazemos:

section .nomeDaSecao

Como dividir um código Assembly: .data, .bss e .text


De uma maneira geral, os programadores Assembly utilizam três sections para organizar seus
códigos. Seguir esses passos é interessante, visto que fará com que seus programas sejam
organizados da maneira padrão, da maneira que é universalmente usada.

Na .data section, como o nome sugere, é uma região do código que será usada para tratar as
informações, os dados, as variáveis.
Nesse trecho (geralmente o inicial), declaramos e inicializamos as variáveis.

Fazemos algo parecido na .bss section, porém não inicializamos as informações.

Por fim, a .text section é o local onde irá ficar armazenado suas instruções, que irão trabalhar com
os dados previamente declarados.
Essa é a única seção obrigatória, pois conterá a label (rótulo) _start, que é o local onde os
executáveis são inicializados.

Se já estudou C, C++ ou Java, por exemplo, a _start seria o main().


Logo, o esqueleto dos códigos em Assembly é:

section .dat
;declaração e inicialização de dados

section .bss
;declaração sem inicialização das informações que serão usadas

section .text
;o programa começa a rodar aqui, a partir da _start

Se comunicando com o mundo externo: global


Como as memórias e processadores estão ficando cada vez mais modernos e maiores (em relação ao
tamanho da memória), está possível, cada vez mais, usar linguagens de alto nível (principalmente o
C), para tarefas que eram feitas exclusivamente em Assembly.

Uma prova disso é o sistema operacional Linux, onde sua gigantesca parte é feita em C, com
algumas pitadas em Assembly.
Essa pitada de Assembly no Kernel é justamente na parte que é necessária uma maior eficiência da
máquina, pois como sabemos, em termos de eficiência nenhuma outra linguagem bate nossa amada
linguagem.
Por isso, é bem comum a interação entre Assembly e outras linguagens. Um exemplo disso são os
games de alto desempenho, que possuem rotinas feitas em Assembly, que se comunica com o resto
do programa.
Ainda em nosso curso de Assembly veremos como usar funções das bibliotecas da linguagem C.

Uma maneira de fazer essa interação é através da diretiva (explicaremos o que é isso em breve)
global.
A diretiva global mostra que o label relacionado é global, ou seja, é passível de uso externamente.
Geralmente usamos para declarar o label principal, o _start.

Portanto, o nosso esqueleto de código será:

section .dat
;declaração e inicialização de dados

section .bss
;declaração sem inicialização das informações que serão usadas

section .text
global _start

_start:
;o programa começa a rodar aqui, a partir daqui

O que é e como usar um Label (rótulo) em Assembly


Agora que já vimos no artigo passado o escopo e organização de um programa em Assembly, vamos
iniciar nossos estudos em programação mesmo, com exemplos reais de códigos ou trechos de
código-fonte.

Neste tutorial de nosso curso Assembly Progressivo, vamos iniciar os nossos estudos das instruções
em Assembly, explicando o que são os labels, labels internos (ou locais), dando exemplos de uso e
mostrando para que servem.

O que são labels em Assembly e para quê servem


A tradução de label é 'rótulo', é uma nomenclatura que damos para dar nome a um trecho de código
em assembly.

Para criar uma label, basta digitar o nome desse rótulo seguido de dois pontos, ' : '.
Em seguida, escrevemos nossas linhas de código em Assembly.
A sintaxe é a seguinte, então:

label:
;aqui vem o código
;que vai ser nomeado
;de 'label'

Imagine que você criou uma rotina de códigos que tem por objetivo passar um número para outro
registrador, subtrair esse valor daquele e depois substituir o valor original (não importa o que sua
rotina esteja fazendo). Enfim, suponha que você criou um trecho de código que vai repetir várias
vezes durante seu programa em Assembly.
Ou seja, esse código se repete, você vai usar mais de uma vez.

Vamos então criar um label chamado 'rotinaBase'.

rotinaBase:
;código super
;hiper mega complexo
;que aprendi no
;Assembly Progressivo

O que o label faz é nomear essa porção de linhas de código.


Para executar elas, em vez de escrever todas elas de novo em outra parte, você apenas se refere a
"rotinaBase", e o trecho de código que você usou abaixo da label 'rotinaBase' será executado.

Lembrando que a linguagem Assembly está em baixo nível, ela sempre trata tudo em relação aos
endereços na memória.Os labels estão intrinsecamente ligados com endereços de memória.

Um label serve para representar o endereço de um determinado trecho no código (ou para inicializar
variáveis e constantes que podem ter seus endereços realocados).
Assim, se usarmos esse trecho de código várias vezes, em vez de repeti-lo basta voltar ao ponto
(endereço) na memória que tem esses códigos.

Porém, é complicado para os humanos tratarem os endereços de memórias como números (em
binário, hexadecimal ou mesmo decimal), por isso damos um nome a esse endereço de memória, um
rótulo, e passamos a chamar esse local da memória pelo seu label. Bem mais simples, não?

No nosso código do Hello World em Assembly, usamos o label '_start', que serve para definir para o
NASM onde vai começar nosso programa.
Como outro exemplo do uso de label em nossos códigos Assembly, vamos supor que durante a
execução de um programa seja necessário incrementar uma variável 'numero' várias vezes.

O código para incrementar é:

inc numero ;numero++

Onde 'inc' é um mnemônico, ou seja, representa a operação de incrementação (adicionar +1 à


variável 'numero'). Vamos criar um label para definir esse trecho de código, a label: 'incrementa'.
Ela ficaria assim:

incrementa:
inc numero ;incrementa 'numero' em uma unidade

Pronto, agora podemos incrementar a variável número apenas invocando o label.

Labels internas ou Labels locais


O uso de labels é altamente recomendável, visto que os programas em baixo nível sempre são
enormes, com códigos 'obscuros', números hexadecimais e outras complicações visuais.
Em sistemas mais complexos, onde é necessário o uso de centenas ou milhares de linhas de código,
será interessante usar labels internas.
Você usará labels que vão representar centenas de linhas de código, e pode ser necessário usar labels
dentro destas labels, e provavelmente que tenham o mesmo nome.

O NASM, que é o Assembler que estamos usando em nosso Curso de Assembly, permite a definição
de labels locais.
Para isso, basta colocar um ponto, ' . ', antes do nome da label.

labelNormal -> label normal, sem ponto


.labelInterna -> label local, com ponto, ela está dentro('pertence) a label 'labelNormal'

Por exemplo, uma representação de um código que duas labels internas, de mesmo nome, mas em
locais diferentes, que fazem a mesma coisa (incrementar), mas incrementam variáveis diferentes:

trecho1:
;trecho 1 do código
.incrementa:
inc numero1

;continuação trecho 1

trecho2:
;trecho 2 do código
.incrementa:
inc numero2

;continuação do trecho 2

Note que uma label local se refere a label 'geral', imediatamente superior.
Cuidado para não se confundir.

Nossos estudos sobre labels não param por aqui, mas você já aprendeu uma ótima noção sobre os
rótulos, embora ainda falte coisas importantes, como o ret, que é uma instrução de retorno, que
serve para definir onde termina um rótulo/label.

Ao decorrer de nossa apostila online de Assembly usaremos bastante labels, então você aprenderá
mais sobre elas vendo exemplos reais de código.

Define - Como alocar memória Assembly - RES, como reservar


memória
Se você estudou somente linguagens de altíssimo nível, como as de linguagens de script, com certeza
nunca se preocupou em alocar memória, pois é tudo feito automaticamente por debaixo dos panos.

Se estudou linguagens como C ou Java, você alocava espaço na memória ao declarar variáveis e
estruturas (em C é possível ainda, a alocação dinâmica de memória).

Nesse tutorial de nosso curso de Assembly, vamos aprender como reservar espaço em disco em
Assembly, ver quais as diferenças e peculiaridades nessa linguagem de baixo nível.
Alocação de memória em programação
Em outras linguagens de programação, para declarar variáveis precisávamos definir o tipo antes.
Por exemplo, em C ou C++, escrevíamos 'int' para inteiros, 'float' ou 'double' para decimais, 'char'
para caracteres, dentre outros tipos.

Ao fazermos isso, sem saber (diferente do Assembly, em que vemos claramente como as coisas são
feitas), estamos dizendo muito mais do que simplesmente a alocação de memória em si.

O resultado de uma operação entre um inteiro e um decimal não é totalmente previsível, depende da
variável em que vamos armazenar, da linguagem e de outras regra específicas.
Quando declaramos uma variável do tipo double ou float, já fica subentendido que haverá uma
vírgula (ou ponto), representado sua parte decimal. Além disso, há divisões no espaço alocado de
memória, para armazenar a parte decimal e a parte não decimal.

Enfim, acontece muito mais do que simplesmente reservar um espaço de memória. Muitas rotinas
úteis, que facilitam a vida de programador acontecem por debaixo dos panos.

Alocação de memória em Assembly - A diretiva define


Obviamente, em Assembly as coisas são um pouco diferente.
Essas coisas que atuam sem o conhecimento do programador simplesmente não existem, e o
profissional que programa em Assembly ficará a cargo de tudo.
Em Assembly, você realmente irá alocar espaço em memória. E somente isso.

Por exemplo, usamos o mnemônico ADD para adicionar um número a outro. Mas ele não vai
simplesmente adicionar todos e quais números automaticamente como costumamos fazer em outras
linguagens.
Se o resultado der mais de dois dígitos, por exemplo, você terá que fazer uma rotina para exibir
esses dois dígitos (sabe quando você soma no papel, fazendo continha e o valor da soma dá mais que
9, aí 'vai 1' ou 'sobe 1' ? é algo parecido) ; ao somar, ter cuidado para saber se somou o caractere '1'
ou realmente o número 1. Case seja caractere, ou queira exibir, terá que fazer alterações, e por aí vai.

Como enfatizamos, Assembly é em baixo nível.


Trabalhamos com bits e bytes. E nesse nível, as coisas não vem prontas.
O programador Assembly é que o tem o poder e responsabilidade de absolutamente tudo. Por isso,
ao alocar memória, temos que definir o número de bytes que vamos usar.

Vamos usar as seguintes variações da diretiva define: DB, DW, DD, DQ e DT.
Eles significam e alocam determinados número de bytes, veja:

DB Define Byte -> aloca 1 byte


DW Define Word -> aloca 2 bytes
DD Define Doubleword -> aloca 4 bytes
DQ Define Quadword -> aloca 8 bytes
DT Define Ten -> aloca 10 bytes

Sabendo disso, poderemos agora mostrar como é a sintaxe de uma instrução em Assembly para
alocar memória:
Nome_da_Variavel diretiva_define valor

Por exemplo, para alocar espaço para o caractere 'A', fazemos:


letra1 DB 'A'
Lembramos que, na verdade, embora tenhamos escrito o caractere 'A', tudo são números.
Então, como na tabela ASCII o valor de 'A', em hexadecimal é 41, poderíamos ter feito:
letra1 DB 41H

Colocamos a letra H ao final do número para dizer que estamos representando em Hexadecimal.
Se fossemos colocar em binário, temos que colocar a letra B ao final:
letra1 DB 01000001B

Para saber mais sobre os caracteres em programação, consulte nosso artigo do site C Progressivo,
que também mostra a tabela ASCII:
http://www.cprogressivo.net/2012/12/O-tipo-char-como-escrever-textos-na-linguagem-C.html

Um pouco de matemática
Em Assembly, trabalhamos sempre com bytes, que equivale a 8 bites.
Cada bit desse pode 0 ou 1, então podemos representar até: 2^8 = 256 caracteres com um byte.

Em Hexadecimal, podemos representar esses 256 caracteres usando os números 00H até FFH.
Ou seja, 41H caberia em um byte, pois é menor que FFH.
Agora 2112H só caberia em dois bytes, onde um armazenaríamos o byte 12H e no outro o byte 21H.

Vamos armazenar uma senha na variável 'senha', ela conterá 4 dígitos decimais: 1234
Esse número, em hexadecimal equivale 4660H.
Precisamos, então, definir dois bytes, ou uma palavra (word). Um byte armazena o 60H e o outro
armazena o 46H.
Para alocar memória para essa senha, faríamos:
senha DW 466H

Outras maneiras de alocar memória em Assembly


E se quiséssemos alocar uma palavra, como 'curso', por exemplo?
Poderíamos alocar letra por letra:
letra1 DB 'c'
letra2 DB 'u'
letra3 DB 'r'
letra4 DB 's'
letra5 DB 'o'

Porém, seria muito trabalhoso, e há maneira mais fáceis de se fazer isso.


Em vez de ter que dar um nome para cada letra (isso não faz o menor sentido!), poderíamos dar um
nome só para o conjunto de letras:
curso DB 'c'
DB 'u'
DB 'r'
DB 's'
DB 'o'

E sempre que usarmos a variável curso, o Assembly saberá que se trata de conjunto de caracteres.
Porém, esse exemplo, assim como o anterior, tem mais caráter de informação para você, leitor de
nosso curso Assembly Progressivo.

A maneira mais prática e utilizada para armazenar uma string, é utilizando a define DB e escrevendo
a string.
O Assembly irá alocar, automaticamente, todos os caracteres, como se tivéssemos feito o exemplo
passado.
No exemplo do "Hello, wolrd" em Assembly, nosso primeiro programa, fizemos isso:
helloWorld DB 'Curso Assembly Progressivo: online, gratis e completo'

Bem mais prático, não?

Reservando memória em Assembly


Até agora, usando a diretiva define e suas variações (DB, DW, DD, DQ e DT), alocamos memória
em Assembly para armazenar e INICIALIZAR variáveis! Porém, nem sempre vamos inicializar,
apenas queremos alocar.
Isso é comum para armazenar variáveis cujos valores serão fornecidos posteriormente, pelo seu
programa, pelo usuário ou um dispositivo de entrada e saída.

Para reservar memória, usamos a diretiva RES, ao mesmo molde da diretiva DEFINE:
RESB Reserve Byte -> reserva 1 byte
RESW Reserve Word -> reserva 2 bytes
RESD Reserve Doubleword -> reserva 4 bytes
RESQ Reserve Quadword -> reserva 8 bytes
REST Reserve Ten -> reserva 10 bytes

A sintaxe é um pouco diferente da DEFINE, já que não vamos inicializar.


Assim, em vez de valor inicial, temos que dizer quanto de espaço queremos reservar, dependendo da
diretiva que usamos.
Sintaxe para reservar memória:
nome_da_variavel diretiva_res numero_de_unidades

Por exemplo:
variavel1 RESB 1 ; nesse caso, reservamos apenas 1 byte
variavel2 RESB 2 ; aqui, reservamos 2 bytes
variavel3 RESW 3 ; 3 palavras são reservadas, o que nos dá 3*2 = 6 bytes
variavel4 REST 10 ; reservamos 10 unidades, de 10 bytes cada

Arrays (vetores) em Assembly - A diretiva TIMES


Neste tutorial de nosso Curso de Assembly, iremos continuar falando sobre a alocação de memória.
No caso, falaremos de alocação de blocos contínuos de memória, popularmente conhecidos como
vetores (C, C++) ou arrays (Java).

Lembramos que vetores e arrays em Assembly são um vasto conteúdo, há uma série de
possibilidades e conceitos por trás desta ideia, e ainda veremos muito sobre o assunto em nosso
curso.
Porém, este tutorial está na seção básica e se destina a apresentar as ideias iniciais, alocação e
inicialização de elementos de um vetor.

Array ou Vetor em Assembly


No tutorial passado de nosso curso falamos sobre as diretivas DEFINE e RES para alocar e reservar
memória, e é de vital importância que você tenha estudado, entendido e com o assunto fresco em
mente para que continuemos nosso curso, pois iremos continuar falando sobre alocar memória em
Assembly.

Naquele artigo mostramos como declarar variáveis, dando um nome para elas e definindo o tanto de
bytes que iremos separar em memória somente para aquelas variáveis, através de comandos como
DB e DW.

Mas se notar bem, alocamos alguns espaços, manualmente.


E se for necessário alocar mil bytes diferentes, para armazenar números quando você for projetar o
hardware de um microondas?
Um sistema como um relógio digital é complexo e pode usar dezenas de milhares de bytes
facilmente, e como os recursos são poucos, é necessário usar a linguagem Assembly.

E é claro que você não vai manusear cada byte desses (embora programadores Assembly sejam
conhecidos por serem escovadores de bits), e é para isso que existem os arrays, também conhecidos
por vetores.

Um vetor, ou array, nada mais é que um bloco enorme de bytes, onde cada bloco é usado como uma
variável, digamos assim, pois trabalhamos diretamente com bytes de memória, não importa se seja
pra um inteiro, caractere ou booleano, pois essas ideias são de linguagens de alto nível, que abstraem
diversos conceitos do que realmente ocorre por debaixo dos panos.

Para nós, vetor ou array em Assembly é um bloco de bytes, geralmente grande, para que possamos
manipular uma quantidade maior de informações de uma maneira bem mais simples, óbvia e lógica.
No decorrer de nosso curso nos depararemos diversas vezes com arrays.

A diretiva TIMES: Como declarar e inicializar um vetor/array em Assembly


Para alocarmos memória usamos a diretiva define, mais conhecida pelas abreviações DW, DD, DQ
etc, e principalmente pela DB (define byte).

Para alocar um bloco de vários bytes ainda utilizaremos a define, mas precisamos dizer quantas
vezes esta alocação deve ocorrer.

Para dizermos o tanto de vezes (de blocos de bytes) que queremos alocar, vamos usar a diretiva
TIMES (que pode ser traduzida como vezes . 3 times -> 3 vezes, 4 times-> 4 vezes).
Em seguida, devemos dizer o número de vezes que a define vai se repetir.

Após nomear, usar a TIMES, dizer o tanto de vezes que a alocação de bytes deve ser feita, devemos
obviamente dizer quantos bytes vão ser alocados por vez.
E como sabemos, para alocar bytes usamos os comandos DB, DW, DD, DQ e DT.

E por fim, devemos dar um valor inicial para esses bytes do bloco de memória.
Você pode alocar 1 milhão de blocos de DT (cada DT aloca 10 bytes), e inicializar cada um deles
com um valor numérico, de forma totalmente automática.

Assim, a sintaxe geral para se declarar um vetor/array em Assembly é:


nomeDoBloco TIMES numeroDeVezes diretivaDEFINE valorInicial

Vamos criar um array de nome "vetor", cada elemento do vetor vai ser alocado através de um DB,
esse vetor terá 10 elementos (então vamos repetir 10 vezes a alocação DB) e vamos inicializar todos
os elementos de nosso array com valor 0:
vetor TIMES 10 DB 0

Agora vamos declarar um vetor de nome "array", ele será composto de 20 elementos do tipo word (2
bytes cada), e será inicializado com o valor hexadecimal FFH:
array TIMES 20 DW FFH

Espaços contíguos de memória Assembly


Um fato interessante que ocorre na linguagem de programação Assembly é que, ao reservar e alocar
espaços de memória, isso é geralmente feito de modo que os blocos de memória sejam contíguos, ou
seja, vizinhos.

Por exemplo, vamos supor que nossa variável "elemento1' ocupe um byte, vamos dizer que na
posição "x" de memória:
elemento1 DB 00H

Se formos, em seguida, alocar a variável "elemento2" que é do tipo e word e ocupa 2 bytes, ela vai
estar na posição "x+1" de memória, pois na posição "x" está o "elemento1" e ele ocupa 1 byte:

A próxima variável que declararmos vai estar na posição "x+3", pois o local "x" é ocupado por
"elemento1" e os dois bytes seguintes é ocupado por "elemento2", concorda?

Vamos fazer a seguinte declaração:


elemento1 DB 00H
elemento2 DW 01H
vetor1 TIMES 10 DB 0
vetor2 TIMES 20 DW 0
elemento3 DD 0

Note que que o "vetor1" ocupa 10x1=10 bytes, pois ele aloca 10 elementos do tipo byte (DB).
E como dissemos, o "vetor1" vai inicial no local de memória "x+3", como ele ocupa 10 bytes, o
próximo vetor vai se iniciar na posição "x+3+10", ou seja, "vetor2" começa na posição "x+13", ok?

Agora vamos analisar "vetor2", ele declara um bloco de memória de 20 elementos do tipo WORD,
onde cada um destes ocupada 2 bytes. Então "vetor2" ocupada 20x2=40 bytes.

Entendeu mesmo?
Então em que posição de memória vai estar localizada a variável "elemento3"?
A resposta está em branco ao lado (seleciona o local com o mouse): x+13+40 = x+53

E caso deseje declarar outra variável abaixo de "elemento3", em que posição de memória esta
variável vai começar? (lembre-se que "elemento3" ocupa 4 bytes): x+

Вам также может понравиться