             i----------------------------------------------
              RBT      Curso de Assembly      Aula N 01 
             ----------------------------------------------

Por: Frederico Pissarra

i------------
 ASSEMBLY I 
------------

    A linguagem ASSEMBLY (e no  assemblER!) d medo em muita gente!
S no sei porque!  As liguagens ditas de  "alto  nvel"  so  MUITO
mais  complexas  que  o  assembly!   O  programador assembly tem que
saber, antes de mais nada, como est organizada a memria da mquina
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 mquina oferece.

    Uma  grande  desvantagem  do  assembly  com  relao  as  outras
linguagens  que  no  existe  tipagem  de  dados como, por exemplo,
ponto-flutuante...  O  programador  ter  que  desenvolver  as  suas
prprias rotinas ou lanar mao do co-processador matemtico (o TURBO
ASSEMBLER,   da   Borland,   fornece   uma   maneira   de  emular  o
co-processador).  No existem funes de entrada-sada como PRINT do
BASIC  ou  o  Write() do PASCAL...  No existem rotinas que imprimam
dados numricos ou strings na  tela...  Enfim...  no existe nada de
til!  (Ser?!  hehehe)

    Pra que serve o  assembly  ento?   A  resposta : Para que voc
possa desenvolver as suas prprias rotinas, sem ter  que  topar  com
bugs  ou  limitaes  de rotinas j existentes na ROM-BIOS ou no seu
compilador  "C",  "PASCAL"  ou  qualquer  outro...   Cabe  aqui  uma
considerao  interessante:    muito  mais  produtivo  usarmos  uma
liguagem de alto nvel juntamente com nossas rotinas em  assembly...
Evita-se a "reinveno da roda" e no temos que desenvolver TODAS as
rotinas  necessrias  para  os  nossos  programas.  Em particular, o
assembly  muito til quando  queremos criar rotinas que no existem
na liguagem de alto-nvel  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  comear  a  entender  alguma  coisa de
assembly  entender como a CPU organiza a memria.   Como  no  nosso
caso a idia  entender os microprocessadores da  famlia  80x86  da
Intel (presentes em qualquer PC-Compatvel), vamos dar uma  olhadela
no modelamento de memria 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 memria - A segmentao 
---------------------------------------------

    A memria de qualquer PC  dividida em segmentos.  Cada segmento
tem 64k bytes  de  tamanho  (65536  bytes)  e  por mais estranho que
parea  os  segmentos  no  so  organizados  de  forma   sequencial
(o  segmento seguinte no comea logo aps o anterior!).  Existe uma
sobreposiao.  De uma olhada:

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

    O  segundo  segmento  comea   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, pacincia,  assim que a  coisa
funciona!

    Para  encontrarmos  um  determinado  byte  dentro de um segmento
precisamos  fornecer  o  OFFSET (deslocamento, em ingls) deste byte
relativo ao inicio  do  segmento.   Assim,  se  queremos localizar o
dcimo-quinto byte do segmento 0, basta especificar 0:15,  ou  seja,
segmento 0 e offset 15.  Esta notao  usada no restante deste e de
outros artigos.

    Na  realidade  a  CPU  faz  o  seguinte clculo para encontrar o
"endereo fsico" ou "endereo efetivo" na memria:

 +-----------------------------------------------------------------+
          ENDEREO-EFETIVO = (SEGMENTO * 16) + OFFSET             
 +-----------------------------------------------------------------+

    Ilustrando  a  complexidade   deste  esquema  de  endereamento,
podemos provar que existem  diversas  formas  de  especificarmos  um
nico "endereo  efetivo"  da  memria...   Por  exemplo, o endereo
0:13Ah pode ser tambm 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 daro
o   mesmo  resultado:  o  endereo-efetivo  0013Ah.   Generalizando,
existem, no mximo,  16  formas  de  especificarmos o mesmo endereo
fsico!  As nicas faixas de endereos que no tem equivalentes e s
podem  ser  especificados  de  uma  nica  forma  so  os  desesseis
primeiros bytes do segmento  0  e  os  ltimos  desesseis  bytes  do
segmento 0FFFFh.

    Normalmente o programador no tem que se preocupar com esse tipo
de coisa.  O compilador toma conta da melhor forma de endereamento.
Mas, como a toda regra existe uma excesso, a informao acima  pode
ser til algum dia.

+-------------------------------------------------------------------+
 A BASE NUMRICA HEXADECIMAL E BINARIA (para os novatos...)        
+-------------------------------------------------------------------+

    Alguns  talvez  no  tenham  conhecimento  sobre as demais bases
numricas usadas na rea informata.    muito comum dizermos "cdigo
hexadecimal", mas o que significa?

     bastante lgico que usemos o sistema decimal  como  base  para
todos  os  clculos  matemticos  do  dia-a-dia pelo simples fato de
temos DEZ dedos nas mos...  fica  facil  contar  nos  dedos  quando
precisamos (hehe).

    Computadores usam o sistema binrio por um outro motimo simples:
Existem apenas dois nveis de tenso presentes em todos os circuitos
lgicos:  nveis  baixo  e  alto  (que  so  chamados  de  0 e 1 por
convenincia...  para podermos medi-los  sem  ter  que recorrer a um
multmetro!).   O  sistema  hexadecimal  tambm tem o seu lugar:  a
forma mais abreviada de escrever um conjunto de bits.

    Em decimal, o nmero 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  potncias.   Fao  agora uma pergunta: Como
representariamos o mesmo nmer se tivessemos 16 dedos nas mos?

     Primeiro teriamos que obter mais digitos...  0 at 9  no  so
      suficientes.   Pegaremos mais 6 letras do alfabeto para suprir
      esta deficiencia.

     Segundo,  Tomemos  como  inspirao  um  odmetro (equipamento
      disponvel  em  qualquer  automvel   -      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 prximo  incrementado,  formando  o  10.   No
      caso  do sistema hexadecimal, isto s acontece quando o ltimo
      algarismo alcana 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 prximo algarismo,
      certo?

    Como contar em base diferente  de  dez   uma situao no muito
intuitiva, vejamos a regra de converso de bases.  Comearemos  pela
base  decimal  para  a  hexadecimal.   Tomemos  o  nmero  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 nmer 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 ento os restos de baixo para cima, formando o nmero em
hexadecimal. Neste caso, 1994=7CAh

    Acrescente um 'h' no fim do nmero para sabermos que se trata da
base  16,  do  contrrio,  se  olharmos  um  nmero "7CA" poderiamos
associa-lo a  qualquer  outra  base  numrica  (base octadecimal por
exemplo!)...

    O processo inverso,  hexa->decimal,    mais  simples...   basta
escrever  o nmer, multiplicando cada digito pela potncia 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 binria (que
tem apenas dois digitos: 0 e  1).   Por  exemplo,  o  nmero  12  em
binrio 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 binria  conhecido como BIT (Binary digIT -
ou  digito  binrio,  em  ingls)!   Note  o  'b'  no  fim do nmero
convertido...

    Faa o processo inverso... Converta 10100110b para decimal.

    A vantagem de usarmos um  nmero  em base hexadecimal  que cada
digito hexadecimal equivale a exatamente  quatro  digitos  binrios!
Faa  as  contas: Quatro bits podem conter apenas 16 nmeros (de 0 a
15), que  exatamente a quantidade de digitos na base hexadecimal.
