
                               ASSEMBLY
                         Comandos e Instrues (Parte 5)
                                Aula nr. 8 de 26

    Veremos agora as instrues de controle de fluxo de programa.

    A CPU sempre executa instrues em  sequncia,  a  no  ser  que
encontre instrues que "saltem" para outra posio na memria.

    Existem  diversas  formas   de   "saltar"  para  um  determinado
endereo:

  Salto incondicional:

    A instruo JMP simplesmente salta  para onde se quer.  Antes de
apresentar a sintaxe, um  detalhe  sobre  codificaao: O operando da
instruo JMP  um endereo na memria, mas, como usaremos sempre um
compilador assembly, necessitamos criar um "rotulo" ou "label"  para
onde  o  salto  ser  efetuado...   O compilador trata de calcular o
endereo pra gente.

    Eis a sintaxe de JMP:

 Ŀ
       JMP Aqui2                                                  
  Aqui1:                                                          
       JMP Aqui3                                                  
  Aqui2:                                                          
       JMP Aqui1                                                  
  Aqui3:                                                          
 

    Os "labels" so sempre seguidos de dois-pontos.  Note, no pedao
de cdigo acima, a quebra da sequncia de execuo.


  Salto Condicional:

    Diferente de JMP, temos instrues que realizam um salto somente
se uma condio  for  satisfeita.   Para  isso,  usa-se os flags.  A
sintaxe dessas instrues depende da condio do flag  que  se  quer
testar. Eis a listagem dessas instrues:

    - JZ "label"  -> Salta se flag Z=1
    - JNZ "label" -> Salta se flag Z=0
    - JC "label"  -> Salta se flag C=1
    - JNC "label" -> Salta se flag C=0
    - JO "label"  -> Salta se flag O=1
    - JNO "label" -> Salta se flag O=0
    - JPO "label" -> Salta se flag P=0 (paridade impar)
    - JPE "label" -> Salta se flag P=1 (paridade par)
    - JS "label"  -> Salta se flag S=1
    - JNS "label" -> Salta se flag S=0

    Existem  ainda mais saltos condicionais para facilitar a vida do
programador:

    - JE "label"  -> Jump if Equal (mesmo que JZ)
    - JNE "label" -> Jump if Not Equal (mesmo que JNZ)
    - JA "label"  -> Jump if Above (salta se acima)
    - JB "label"  -> Jump if Below (salta se abaixo)
    - JAE "label" -> Jump if Above or Equal (salta se acima ou =)
    - JBE "label" -> Jump if Below of Equal (salta se abaixo ou =)
    - JG "label"  -> Jump if Greater than (salta se >)
    - JL "label"  -> Jump if Less than (salta se <)
    - JGE "label" -> Jump if Greater than or Equal (salta se >=)
    - JLE "label" -> Jump if Less or Equal (salta se <=)

    A diferena entre JG e JA, JL e JB :

    - JA e JB so relativos a comparaes sem sinal.
    - JG e JL so relativos a comparaes com sinal.

    Os  saltos  condicionais  tm  uma  desvantagem  com relao aos
saltos incondicionais: O deslocamento  relativo a posio corrente,
isto , embora no nosso cdigo o salto se d na posio do "label" o
assembler traduz esse salto para  uma  posio "x" bytes para frente
ou para tras em relao a posio da instruo de salto...   e  esse
nmero  "x"  est  na  faixa de -128 a 127 (traduzindo isso tudo pra
quem no entendeu: No  possvel saltos muito longos com instrues
de salto condicionais...   salvo  em  casos especiais que explicarei
mais tarde!).

    Existe ainda a  instruo  JCXZ.   Essa  instruo  salta  se  o
registrador CX for 0.

    Mais uma instruo: LOOP

    A  instruo  LOOP  salta  para  um  determinado  endereo  se o
registrador CX for diferente de zero e, antes de saltar,  decrementa
CX. Um exemplo do uso desta instruo:

 Ŀ
       SUB AL,AL       ;AL = 0                                    
       SUB DI,DI       ;DI = 0                                    
       MOV CX,1000     ;CX = 1000                                 
   Loop1:                                                         
       MOV BYTE PTR ES:[DI],0  ;Poe 0 em ES:DI                    
       INC DI          ;Incrementa o offset (DI)                  
       LOOP Loop1      ;Repete ate' que CX seja 0                 
 

    Essa  rotina  preenche  os  1000 bytes a partir de ES:0 com 0. O
modificador "BYTE PTR" na frente de ES:[DI] resolve uma ambiguidade:
Como podemos saber se a  instruo "MOV ES:[DI],0" escrever um byte
ou um word?  Por default, o compilador assume word, por  isso  temos
que usar o modificador indicando que queremos byte.

    Repare que o pedao entre "Loop1" e o final da rotina equivale a
uma instruo "REP STOSB".

    Podemos tambm especificar uma instruo LOOP condicional, basta
acrescentar  'Z'  ou  'NZ'  (ou os equivalentes 'E' ou 'NE') no fim.
Isto quer dizer: Salte  ENQUANTO  CX  for  ZERO  (Z) ou NO for ZERO
(NZ).  A instruo LOOP sem condio  a mesma coisa que  LOOPNZ  ou
LOOPNE!


  Chamadas a sub-rotinas:

    A instruo CALL funciona como se fosse  a  instruo  GOSUB  do
velho BASIC.  Ela  salta  para  a  posio  especificada  e quando a
instruo RET for encontrada na sub-rotina a CPU salta de volta para
a prxima instruo que segue o CALL. A sintaxe:

 Ŀ
   CALL "label"                                                   
 

    Eis um exemplo:

 Ŀ
       MOV AL,9        ;Poe numero em AL                          
       CALL ShowNumber ;Salta para a subrotina                    
       ...                                                        
                                                                  
   ShowNumber:                                                    
       ...                                                        
       RET     ;Retorna                                           
 
                               
