Pesquisar Neste Blog 1

Curso de Assembly - Aula Nº 01

0
Curso de Assembly - Aula Nº 01

 i--------------------------------------------©
Curso de Assembly   ¦   Aula Nº 01
È--------------------------------------------¥

 i-----------------------©
ASSEMBLY I
È-----------------------¥

A linguagem ASSEMBLY (e näo  assemblER!) dá medo em muita gente!
Só näo sei porque!  As liguagens ditas de  "alto  nível"  säo  MUITO
mais  complexas  que  o  assembly!   O  programador assembly tem que
saber, antes de mais nada, como está organizada a memória da máquina
em que trabalha, a  disponibilidade  de rotinas pré-definidas na ROM
do  micro  (que facilita muito a vida de vez em quando!) e os demais
recursos que a máquina oferece.

Uma  grande  desvantagem  do  assembly  com  relaçäo  as  outras
linguagens é que  näo  existe  tipagem  de  dados como, por exemplo,
ponto-flutuante...  O  programador  terá  que  desenvolver  as  suas
próprias rotinas ou lançar mao do co-processador matemático (o TURBO
ASSEMBLER,   da   Borland,   fornece   uma   maneira   de  emular  o
co-processador).  Näo existem funçöes de entrada-saída como PRINT do
BASIC  ou  o  Write() do PASCAL...  Näo existem rotinas que imprimam
dados numéricos ou strings na  tela...  Enfim...  näo existe nada de
útil!  (Será?!  hehehe)

Pra que serve o  assembly  entäo?   A  resposta é: Para que você
possa desenvolver as suas próprias rotinas, sem ter  que  topar  com
bugs  ou  limitaçöes  de rotinas já existentes na ROM-BIOS ou no seu
compilador  "C",  "PASCAL"  ou  qualquer  outro...   Cabe  aqui  uma
consideraçäo  interessante:  É  muito  mais  produtivo  usarmos  uma
liguagem de alto nível juntamente com nossas rotinas em  assembly...
Evita-se a "reinvençäo da roda" e näo temos que desenvolver TODAS as
rotinas  necessárias  para  os  nossos  programas.  Em particular, o
assembly é muito útil quando  queremos criar rotinas que näo existem
na liguagem de alto-nível  nativa!   Uma rotina ASM bem desenvolvida
pode nos dar a vantagem da velocidade ou do tamanho mais reduzido em
nossos programas.

O  primeiro  passo  para  começar  a  entender  alguma  coisa de
assembly é entender como a CPU organiza a memória.   Como  no  nosso
caso a idéia é entender os microprocessadores da  família  80x86  da
Intel (presentes em qualquer PC-Compatível), vamos dar uma  olhadela
no modelamento de memória usado pelos PCs, funcionando sob o  MS-DOS
(Windows,  OS/2,  UNIX,  etc...   usam  outro tipo de modelamento...
MUITO MAIS COMPLICADO!).

i---------------------------------------------------------------©
Modelamento REAL da memória - A segmentaçäo
È---------------------------------------------------------------¥

A memória de qualquer PC é dividida em segmentos.  Cada segmento
tem 64k bytes  de  tamanho  (65536  bytes)  e  por mais estranho que
pareça  os  segmentos  näo  säo  organizados  de  forma   sequencial
(o  segmento seguinte näo começa logo após o anterior!).  Existe uma
sobreposiçao.  De uma olhada:

                                         64k                                            
+------------------------------------------------------------+
¦                                                                                 ¦
¦       ¦        ¦                                                                 ¦
0      1      2     <- Numero do segmento                         
+-------------+                                                                 
       16     16                                                                   
 bytes   bytes                                                             

O  segundo  segmento  começa   exatamente  16  bytes  depois  do
primeiro.  Deu pra perceber que o inicio do  segundo  segmento  está
DENTRO do primeiro, já que os segmentos tem 64k de tamanho!

Este  esquema  biruta  confunde  bastante os programadores menos
experientes e,  até  hoje,  ninguem  sabe  porque  a  Intel resolveu
utilizar essa coisa esquisita.  Mas, paciência, é assim que a  coisa
funciona!

Para  encontrarmos  um  determinado  byte  dentro de um segmento
precisamos  fornecer  o  OFFSET (deslocamento, em inglês) deste byte
relativo ao inicio  do  segmento.   Assim,  se  queremos localizar o
décimo-quinto byte do segmento 0, basta especificar 0:15,  ou  seja,
segmento 0 e offset 15.  Esta notaçäo é usada no restante deste e de
outros artigos.

Na  realidade  a  CPU  faz  o  seguinte cálculo para encontrar o
"endereço físico" ou "endereço efetivo" na memória:

ENDEREÇO-EFETIVO = (SEGMENTO * 16) + OFFSET

Ilustrando  a  complexidade   deste  esquema  de  endereçamento,
podemos provar que existem  diversas  formas  de  especificarmos  um
único "endereço  efetivo"  da  memória...   Por  exemplo, o endereço
0:13Ah pode ser também escrito como:

0001h:012Ah     0002h:011Ah     0003h:010Ah     0004h:00FAh
0005h:00EAh     0006h:00DAh     0007h:00CAh     0008h:00BAh
0009h:00AAh     000Ah:009Ah     000Bh:008Ah     000Ch:007Ah
000Dh:006Ah     000Eh:005Ah     000Fh:004Ah     0010h:003Ah
0011h:002Ah     0012h:001Ah     0013h:000Ah

Basta fazer as contas que você verá que todas estas formas daräo
o   mesmo  resultado:  o  endereço-efetivo  0013Ah.   Generalizando,
existem, no máximo,  16  formas  de  especificarmos o mesmo endereço
físico!  As únicas faixas de endereços que näo tem equivalentes e só
podem  ser  especificados  de  uma  única  forma  säo  os  desesseis
primeiros bytes do segmento  0  e  os  últimos  desesseis  bytes  do
segmento 0FFFFh.

Normalmente o programador näo tem que se preocupar com esse tipo
de coisa.  O compilador toma conta da melhor forma de endereçamento.
Mas, como a toda regra existe uma excessäo, a informaçäo acima  pode
ser útil algum dia.

A BASE NUMÉRICA HEXADECIMAL E BINARIA (para os novatos...)

Alguns  talvez  näo  tenham  conhecimento  sobre as demais bases
numéricas usadas na área informata.   É muito comum dizermos "código
hexadecimal", mas o que significa?

É bastante lógico que usemos o sistema decimal  como  base  para
todos  os  cálculos  matemáticos  do  dia-a-dia pelo simples fato de
temos DEZ dedos nas mäos...  fica  facil  contar  nos  dedos  quando
precisamos (hehe).

Computadores usam o sistema binário por um outro motimo simples:
Existem apenas dois níveis de tensäo presentes em todos os circuitos
lógicos:  níveis  baixo  e  alto  (que  säo  chamados  de  0 e 1 por
conveniência...  para podermos medi-los  sem  ter  que recorrer a um
multímetro!).   O  sistema  hexadecimal  também tem o seu lugar: é a
forma mais abreviada de escrever um conjunto de bits.

Em decimal, o número 1994, por exemplo, pode ser escrito como:

1994 = (1 * 10^3) + (9 * 10^2) + (9 * 10^1) + (4 * 10^0)

Note a base 10  nas  potências.   Faço  agora uma pergunta: Como
representariamos o mesmo númer se tivessemos 16 dedos nas mäos?

¦ Primeiro teriamos que obter mais digitos...  0 até 9  näo  säo
suficientes.   Pegaremos mais 6 letras do alfabeto para suprir
esta deficiencia.

    ¦ Segundo,  Tomemos  como  inspiraçäo  um  odômetro (equipamento
disponível  em  qualquer  automóvel   -   é   o   medidor   de
quilometragem!):  Quando  o  algarismo mais a direita (o menos
significativo) chega a 9  e  é  incrementado, o que ocorre?...
Retorna a 0 e o próximo é incrementado,  formando  o  10.   No
caso  do sistema hexadecimal, isto só acontece quando o último
algarismo alcança F e é  incrementado!   Depois  do 9 vem o A,
depois o B, depois o C, e assim por diante...   até  chegar  a
vez  do  F e saltar para 0, incrementando o próximo algarismo,
certo?

Como contar em base diferente  de  dez  é uma situaçäo näo muito
intuitiva, vejamos a regra de conversäo de bases.  Começaremos  pela
base  decimal  para  a  hexadecimal.   Tomemos  o  número  1994 como
exemplo.   A  regra  é   simples:   Divide-se   1994  por  16  (base
hexadecimal) até que o quoeficiente seja zero...  toma-se os  restos
e tem-se o númer convertido para hexadecimal:

1994 / 16     -> Q=124, R=10      -> 10=A
124 / 16      -> Q=7, R=12        -> 12=C
7 / 16        -> Q=0, R=7         ->  7=7

Toma-se entäo os restos de baixo para cima, formando o número em
hexadecimal. Neste caso, 1994=7CAh

Acrescente um 'h' no fim do número para sabermos que se trata da
base  16,  do  contrário,  se  olharmos  um  número "7CA" poderiamos
associa-lo a  qualquer  outra  base  numérica  (base octadecimal por
exemplo!)...

O processo inverso,  hexa->decimal,  é  mais  simples...   basta
escrever  o númer, multiplicando cada digito pela potência correta,
levando-se em conta a equivalencia das letras com a base decimal:

7CAh = (7 * 16^2) + (C * 16^1) + (A * 16^0) =
(7 * 16^2) + (12 * 16^1) + (10 * 16^0) =
1792 + 192 + 10 = 1994

As mesmas regras podem  ser  aplicadas  para a base binária (que
tem apenas dois digitos: 0 e  1).   Por  exemplo,  o  número  12  em
binário fica:

12 / 2      -> Q=6, R=0
6 / 2       -> Q=3, R=0
3 / 2       -> Q=1, R=1
1 / 2       -> Q=0, R=1
12 = 1100b

Cada digito na base binária é conhecido como BIT (Binary digIT -
ou  digito  binário,  em  inglês)!   Note  o  'b'  no  fim do número
convertido...

Faça o processo inverso... Converta 10100110b para decimal.

A vantagem de usarmos um  número  em base hexadecimal é que cada
digito hexadecimal equivale a exatamente  quatro  digitos  binários!
Faça  as  contas: Quatro bits podem conter apenas 16 números (de 0 a
15), que é exatamente a quantidade de digitos na base hexadecimal.

Postar um comentário

0 Comentários
* Por Favor, Não Faça Spam Aqui. Todos os Comentários São Revisados Pelo Administrador.
Postar um comentário (0)

#buttons=(Aceito !) #days=(365)

COOKIES: Esse Site Guarda Estatísticas de Visitas Para Melhorar a Sua Experiência de Navegação e Disponibilizar Funcionalidades Adicionais, Saiba Mais em Nossa Política de Privacidade
Aceito !