<Índice> <1> <2> <3> <4> <5> <6> <7> <8> <Página Principal>

CAPÍTULO 7:
EXEMPLOS DE PROGRAMAS
                           
                               
Conteúdo:
7.1.Exemplos de Programas com Debug
7.2.Exemplos de Programas com TASM                         
			--------------- // ---------------
7.1.Exemplos de Programas com Debug
Nesta seção forneceremos alguns programas feitos no debug do DOS.
Você pode executar cada programa assembly usando o comando "g" (go), para
ver o que cada programa faz.
Procedimento
Primeiro passo
Carregar o programa exemplo
Por exemplo:
C:\>debug
-n one.com
-l
-u 100 109
0D80:0100 B80600        MOV     AX,0006
0D80:0103 BB0400        MOV     BX,0004
0D80:0106 01D8          ADD     AX,BX
0D80:0108 CD20          INT     20
-
Nota:
-n one.com
Dar nome ao programa a ser carregado
-l
Carregá-lo
-u 100 109
Desmontar o código do endereço inicial ao final especificado
Segundo passo
Digite o comando g
Por exemplo:
-g
Program terminated normally
-
                                   
Exemplos de programas no Debug
Primeiro exemplo
-a0100
297D:0100     MOV     AX,0006    ;Põe o valor 0006 no registrador AX
297D:0103     MOV     BX,0004    ;Põe o valor 0004 no registrador BX
297D:0106     ADD     AX,BX      ;Adiciona BX ao conteúdo de AX
297D:0108     INT     20         ;Finaliza o Programa
A única coisa que este programa faz é salvar dois valores em dois
registradores e adicionar o valor de um ao outro.

Segundo exemplo
- a100
0C1B:0100 jmp 125 ;Salta para o endereço 125h
0C1B:0102 [Enter]
- e 102  'Hello, How are you ?' 0d 0a '$'
- a125
0C1B:0125 MOV DX,0102 ;Copia a string para registrador DX
0C1B:0128 MOV CX,000F ;Quantas vezes a string ser  mostrada
0C1B:012B MOV AH,09   ;Copia o valor 09 para registrador AH
0C1B:012D INT 21      ;Mostra a string
0C1B:012F DEC CX      ;Subtrai 1 de CX
0C1B:0130 JCXZ 0134   ;Se CX ‚ igual a 0 salta para o endereço 0134
0C1B:0132 JMP 012D    ;Salta ao endereço 012D
0C1B:0134 INT 20      ;Finaliza o programa
Este programa mostra 15 vezes na tela a string de caracteres.

Terceiro exemplo
-a100
297D:0100       MOV     AH,01    ;Função para mudar o cursor
297D:0102       MOV     CX,0007  ;Formata o cursor
297D:0105       INT     10       ;Chama interrupção do BIOS
297D:0107       INT     20       ;Finaliza o programa
Este programa muda o formato do cursor.

 

Quarto exemplo
-a100
297D:0100       MOV     AH,01    ;Função 1 (lê caractere do teclado)
297D:0102       INT     21       ;Chama interrupção do DOS
297D:0104       CMP     AL,0D    ;Compara se o caractere lido é um ENTER
297D:0106       JNZ     0100     ;Se não é, lê um outro caractere
297D:0108       MOV     AH,02    ;Função 2 (escreve um caractere na tela)
297D:010A       MOV     DL,AL    ;Character to write on AL
297D:010C       INT     21       ;Chama interrupção do DOS
297D:010E       INT     20       ;Finaliza o programa
Este programa usa a interrupção 21h do DOS. Usa duas funções da mesma: a
primeira lê um caractere do teclado (função 1) e a segundo escreve um
caractere na tela. O programa lê caracteres do teclado até encontrar um
ENTER.

 

Quinto exemplo
-a100
297D:0100       MOV     AH,02     ;Função 2 (escreve um caractere na tela)
297D:0102       MOV     CX,0008   ;Põe o valor 0008 no registrador CX
297D:0105       MOV     DL,00     ;Põe o valor 00 no registrador DL
297D:0107       RCL     BL,1      ;Rotaciona o byte em BL um bit para a esquerda
297D:0109       ADC     DL,30     ;Converte o registrador de flag para 1
297D:010C       INT     21        ;Chama interrupção do DOS
297D:010E       LOOP    0105      ;Salta se CX > 0 para o endereço 0105
297D:0110       INT     20        ;Finaliza o programa
Este programa mostra na tela um número binário através de um ciclo
condicional (LOOP) usando a rotação do byte.

 

Sexto exemplo
-a100
297D:0100       MOV     AH,02     ;Função 2 (escreve um caractere na tela)
297D:0102       MOV     DL,BL     ;Põe o valor de BL em DL
297D:0104       ADD     DL,30     ;Adiciona o valor 30 a DL
297D:0107       CMP     DL,3A     ;Compara o valor 3A com o conteúdo de DL sem afetá-lo
                                  ;seu valor apenas modifica o estado do flag de carry
297D:010A       JL      010F      ;salta ao endereço 010f, se for menor
297D:010C       ADD     DL,07     ;Adiciona o valor 07 a DL
297D:010F       INT     21        ;Chama interrupção do DOS
297D:0111       INT     20        ;Finaliza o programa
Este programa imprime um valor zero em dígitos hexadecimais.

Sétimo exemplo
-a100
297D:0100       MOV     AH,02    ;Função 2 (escreve um caractere na tela)
297D:0102       MOV     DL,BL    ;Põe o valor de BL em DL
297D:0104       AND     DL,0F    ;Transporta fazendo AND dos números bit a bit
297D:0107       ADD     DL,30    ;Adiciona 30 a Dl
297D:010A       CMP     DL,3A    ;Compara Dl com 3A
297D:010D       JL      0112     ;Salta ao endereço 0112, se menor
297D:010F       ADD     DL,07    ;Adiciona 07 a DL
297D:0112       INT     21       ;Chama interrupção do DOS
297D:0114       INT     20       ;Finaliza o programa
Este programa é usado para imprimir dois dígitos hexadecimais.

 

Oitavo exemplo
-a100
297D:0100     MOV     AH,02    ;Função 2 (escreve um caractere na tela)
297D:0102     MOV     DL,BL    ;Põe o valor de BL em DL
297D:0104     MOV     CL,04    ;Põe o valor 04 em CL
297D:0106     SHR     DL,CL    ;Desloca os 4 bits mais altos do número ao nibble mais á direita
297D:0108     ADD     DL,30    ;Adiciona 30 a DL
297D:010B     CMP     DL,3A    ;Compara Dl com 3A
297D:010E     JL      0113     ;Salta ao endereço 0113, se menor
297D:0110     ADD     DL,07    ;Adiciona 07 a DL
297D:0113     INT     21       ;Chama interrupção do DOS
297D:0115     INT     20       ;Finaliza o programa
Este programa imprime o primeiro de dois dígitos hexadecimais.

 

Nono exemplo
-a100
297D:0100     MOV     AH,02   ;Função 2 (escreve um caractere na tela)
297D:0102     MOV     DL,BL   ;Põe o valor de BL em DL
297D:0104     MOV     CL,04   ;Põe o valor 04 em CL
297D:0106     SHR     DL,CL   ;Desloca os 4 bits mais altos do número ao nibble mais á direita
297D:0108     ADD     DL,30   ;Adiciona 30 a DL
297D:010B     CMP     DL,3A   ;Compara Dl com 3A
297D:010E     JL      0113    ;Salta ao endereço 0113, se menor
297D:0110     ADD     DL,07   ;Adiciona 07 a DL
297D:0113     INT     21      ;Chama interrupçãoo do DOS
297D:0115     MOV     DL,BL   ;Põe o valor de BL em DL
297D:0117     AND     DL,0F   ;Transporta fazendo AND dos números bit a bit
297D:011A     ADD     DL,30   ;Adiciona 30 a DL 
297D:011D     CMP     DL,3A   ;Compara Dl com 3A
297D:0120     JL      0125    ;Salta ao endereço 0125, se menor
297D:0122     ADD     DL,07   ;Adiciona 07 a DL
297D:0125     INT     21      ;Chama interrupção do DOS
297D:0127     INT     20      ;Finaliza o programa
Este programa imprime o segundo de dois dígitos hexadecimais.

 

Décimo exemplo
-a100
297D:0100      MOV     AH,01   ;Função 1 (lê caractere do teclado)
297D:0102      INT     21      ;Chama interrupção do DOS
297D:0104      MOV     DL,AL   ;Põe o valor de AL em DL
297D:0106      SUB     DL,30   ;Subtrai 30 de DL
297D:0109      CMP     DL,09   ;Compara DL com 09
297D:010C      JLE     0111    ;Salta ao endereço 0111, se menor ou igual
297D:010E      SUB     DL,07   ;Subtrai 07 de DL
297D:0111      MOV     CL,04   ;Põe o valor 04 em CL
297D:0113      SHL     DL,CL   ;Insere zeros á direita
297D:0115      INT     21      ;Chama interrupção do DOS
297D:0117      SUB     AL,30   ;Subtrai 30 de AL
297D:0119      CMP     AL,09   ;Compara AL com 09
297D:011B      JLE     011F    ;Salta ao endereço 011f, se menor ou igual
297D:011D      SUB     AL,07   ;Subtrai 07 de AL
297D:011F      ADD     DL,AL   ;Adiciona AL a DL
297D:0121      INT     20      ;Finaliza o programa

 

Este programa pode ler dois dígitos hexadecimais.

 

Décimo primeiro exemplo
-a100
297D:0100     CALL    0200   ;Chama um procedimento
297D:0103     INT     20     ;Finaliza o programa
-a200
297D:0200     PUSH    DX     ;Põe o valor de DX na pilha
297D:0201     MOV     AH,08  ;Função 8
297D:0203     INT     21     ;Chama interrupção do DOS
297D:0205     CMP     AL,30  ;Compara AL com 30
297D:0207     JB      0203   ;Salta se CF é ativado ao endereço 0203
297D:0209     CMP     AL,46  ;Compara AL com 46
297D:020B     JA      0203   ;Salta ao endereço 0203, se diferente
297D:020D     CMP     AL,39  ;Compara AL com 39
297D:020F     JA      021B   ;Salta ao endereço 021B, se diferente
297D:0211     MOV     AH,02  ;Função 2 (escreve um caractere na tela)
297D:0213     MOV     DL,AL  ;Põe o valor de AL em DL
297D:0215     INT     21     ;Chama interrupção do DOS
297D:0217     SUB     AL,30  ;Subtrai 30 de AL
297D:0219     POP     DX     ;Extrai o valor de DX da pilha
297D:021A     RET            ;Retorna o controle ao programa principal
297D:021B     CMP     AL,41  ;Compara AL com 41
297D:021D     JB      0203   ;Salta se CF é ativado ao endereço 0203
297D:021F     MOV     AH,02  ;Função 2 (escreve um caractere na tela)
297D:022      MOV     DL,AL  ;Põe o valor AL em DL
297D:0223     INT     21     ;Chama interrupção do DOS
297D:0225     SUB     AL,37  ;Subtrai 37 de AL
297D:0227     POP     DX     ;Extrai o valor de DX da pilha
297D:0228     RET            ;Retorna o controle ao programa principal
Este programa se mantém lendo caracteres até receber um que possa ser
convertido para um número hexadecimal.
			--------------- // ---------------
7.2.Exemplos de Programas com TASM                         
Nesta seção forneceremos a você vários exemplos de programas a serem
montados fazendo uso do TASM da Borland.
Procedimento:
Para montá-los, siga os seguintes passos:
Primeiro passo
Montar o programa
Por exemplo:
C:\>tasm one.asm
Turbo Assembler  Version 2.0  Copyright (c) 1988, 1990 Borland International 
Assembling file:   one.asm
Error messages:    None
Warning messages:  None
Passes:            1
Remaining memory:  471k
C:\>
Isto criará um programa objeto com o mesmo nome do fonte, neste caso:
one.obj
Segundo passo
Criar o programa executável
Por exemplo:
C:\>tlink one.obj
Turbo Link  Version 3.0 Copyright (c) 1987, 1990 Borland International
C:\> 
Isto cria o programa executável com o mesmo nome do objeto e com extensão
diferente, one.exe

Terceiro passo
Rodar o programa executável. Basta digitar o nome do programa criado.
                                   
Exemplos de Programas Assembly

Primeiro exemplo
;nome do programa: one.asm
;
.model small
.stack
.code
   mov AH,1h       ;Função 1 do DOS
   Int 21h         ;lê o caracter e returna o código ASCII ao registrador AL
   mov DL,AL       ;move o código ASCII para o registrador DL
   sub DL,30h      ;subtrai de 30h para converter a um dígito de 0 a 9
   cmp DL,9h       ;compara se o dígito está entre 0 e 9
   jle digit1      ;se verdadeiro obtém o primeiro número (4 bits)
   sub DL,7h       ;se falso, subtrai de 7h para converter a uma letra A-F
digit1:
   mov CL,4h       ;prepara para multiplicar por 16
   shl DL,CL       ;multiplica para converter dentro dos 4 bits mais altos
   int 21h         ;obtém o próximo caracter
   sub AL,30h      ;repete a operação de conversão
   cmp AL,9h       ;compara o valor 9h com o conteúdo do registrador AL
   jle digit2      ;se verdadeiro, obtém o segundo dígito
   sub AL,7h       ;se falso, subtrai de 7h
digit2:
   add DL,AL       ;adiciona o segundo dígito
   mov AH,4Ch      ;função 4Ch do DOS (exit)
   Int 21h         ;interrupção 21h
   End             ;finaliza o programa
Este programa lê dois caracteres e os imprime na tela

 

Segundo exemplo
;nome do programa: two.asm
.model small
.stack
.code
PRINT_A_J       PROC
     MOV DL,'A'      ;move o character A para o registrador DL
     MOV CX,10       ;move o valor decimal 10 para o registrador CX
                     ;este valor é usado para fazer laço com 10 interações
PRINT_LOOP:
     CALL WRITE_CHAR ;Imprime o caracter em DL
     INC DL          ;Incrementa o valor do registrador DL
     LOOP PRINT_LOOP ;Laço para imprimir 10 caracteres
     MOV AH,4Ch      ;Função 4Ch, para sair ao DOS
     INT 21h         ;Interrupção 21h
PRINT_A_J       ENDP ;Finaliza o procedimento
WRITE_CHAR      PROC
     MOV AH,2h       ;Função 2h, imprime caracter
     INT 21h         ;Imprime o caracter que está em DL
     RET             ;Retorna o controle ao procedimento que chamou
WRITE_CHAR      ENDP ;Finaliza o procedimento
     END  PRINT_A_J  ;Finaliza o programa
Este programa mostra os caracteres ABCDEFGHIJ na tela.

 

Terceiro exemplo
;nome do programa: three.asm
.model small
.STACK
.code
TEST_WRITE_HEX    PROC
      MOV DL,3Fh      ;Move o valor 3Fh para o registrador DL
      CALL WRITE_HEX  ;Chama a sub-rotina
      MOV AH,4CH      ;Função 4Ch
      INT 21h         ;Retorna o controle ao DOS
TEST_WRITE_HEX ENDP   ;Finaliza o procedimento
      PUBLIC WRITE_HEX
;........................................................;
;Este procedimento converte para hexadecimal o byte      ;
;armazenado no registrador DL e mostra o dígito          ;
;Use:WRITE_HEX_DIGIT                                     ;
;........................................................;
WRITE_HEX    PROC
      PUSH CX        ;coloca na pilha o valor do registrador CX
      PUSH DX        ;coloca na pilha o valor do registrador DX
      MOV DH,DL      ;move o valor do registrador DL para o registrador DH
      MOV CX,4       ;move o valor 4 para o registrador CX
      SHR DL,CL
CALL WRITE_HEX_DIGIT ;mostra na tela o primeiro número hexadecimal
      MOV DL,DH      ;move o valor do registrador DH para o registrador DL
      AND DL,0Fh
CALL WRITE_HEX_DIGIT ;mostra na tela o segundo número hexadecimal
      POP DX         ;retira da pilha o valor do registrador DX
      POP CX         ;retira da pilha o valor do registrador CX
      RET            ;Retorna o controle ao procedimento que chamou
WRITE_HEX  ENDP
     
 PUBLIC WRITE_HEX_DIGIT
;......................................................................;
;Este procediento converte os 4 bits mais baixos do registrador DL     ;
;para um número hexadecimal e o mostra na tela do computador           ;
;Use: WRITE_CHAR                                                       ;
;......................................................................;
WRITE_HEX_DIGIT    PROC
      PUSH DX               ;coloca na pilha o valor de DX
      CMP DL,10             ;compara se o número de bits é menor do que 10
      JAE HEX_LETTER        ;se não, salta para HEX_LETER
      ADD DL,"0"            ;se sim, converte para número
      JMP Short WRITE_DIGIT ;escreve o caracter
HEX_LETTER:
      ADD DL,"A"-10         ;converte um caracter para hexadecimal
WRITE_DIGIT:
      CALL WRITE_CHAR       ;imprime o caracter na tela
      POP DX                ;Retorna o valor inicial do registrador DX
                            ;para o registrador DL
      RET                   ;Retorna o controle ao procedimento que chamou
WRITE_HEX_DIGIT   ENDP
    
  PUBLIC WRITE_CHAR
;......................................................................;
;Este procedimento imprime um caracter na tela usando o D.O.S.         ;
;......................................................................;
WRITE_CHAR   PROC
      PUSH AX       ;Coloca na pilha o valor do registarador AX
      MOV AH,2      ;Função 2h
      INT 21h       ;Interrupção 21h
      POP AX        ;Extrai da pilha o valor de AX
      RET           ;Retorna o controle ao procedimento que chamou
WRITE_CHAR   ENDP
      END TEST_WRITE_HEX ;Finaliza o programa



Quarto exemplo
;nome do programa: four.asm
.model small
.stack
.code
TEST_WRITE_DECIMAL    PROC
      MOV DX,12345       ;Move o valor decimal 12345 para o registrador DX
      CALL WRITE_DECIMAL ;Chama o procedimento
      MOV AH,4CH         ;Função 4Ch
      INT 21h            ;Interrupção 21h
TEST_WRITE_DECIMAL ENDP  ;Finaliza o procedimento
     
 PUBLIC WRITE_DECIMAL
;.................................................................;
;Este procedimento escreve um número de 16 bit como um número     ;
;sem sinal em notação decimal                                     ;
;Use: WRITE_HEX_DIGIT                                             ;
;.................................................................;
WRITE_DECIMAL    PROC
      PUSH AX   ;Põe na pilha o valor do registrador AX
      PUSH CX   ;Põe na pilha o valor do registrador CX
      PUSH DX   ;Põe na pilha o valor do registrador DX
      PUSH SI   ;Põe na pilha o valor do registrador SI
      MOV AX,DX ;move o valor do registrador DX para AX
      MOV SI,10 ;move o valor 10 para o registrador SI
      XOR CX,CX ;zera o registrador CX
NON_ZERO:
      XOR DX,DX ;zera o registrador CX
      DIV SI    ;divisão entre SI
      PUSH DX   ;Põe na pilha o valor do registrador DX
      INC CX    ;incrementa CX
      OR AX,AX  ;não zero
      JNE NON_ZERO  ;salta para NON_ZERO
WRITE_DIGIT_LOOP:
      POP DX    ;Retorna o valor em modo reverso
      CALL WRITE_HEX_DIGIT  ;Chama o procedimento
      LOOP WRITE_DIGIT_LOOP ;loop
END_DECIMAL:
      POP SI    ;retira da pilha o valor do registrador SI
      POP DX    ;retira da pilha o valor do registrador DX
      POP CX    ;retira da pilha o valor do registrador CX
      POP AX    ;retira da pilha o valor do registrador AX
      RET       ;Retorna o controle ao procedimento que chamou
WRITE_DECIMAL   ENDP ;Finaliza o procedimento

 

      PUBLIC WRITE_HEX_DIGIT
;......................................................................;
;                                                                      ;
;Este procedimento converte os 4 bits mais baixos do registrador DL    ;
;num n�mero hexadecimal e os imprime                                   ;
;Use: WRITE_CHAR                                                       ;
;......................................................................;
WRITE_HEX_DIGIT    PROC
      PUSH DX         ;Põe na pilha o valor do registrador DX
      CMP DL,10       ;Compara o valor 10 com o valor do registrador DL
      JAE HEX_LETTER  ;se n�o, salta para HEX_LETER
      ADD DL,"0"      ;se ‚, converte em d�gito num‚rico
      JMP Short WRITE_DIGIT ;escreve o caracter
HEX_LETTER:
      ADD DL,"A"-10   ;converte um caracter para um n�mero hexadecimal
WRITE_DIGIT:
      CALL WRITE_CHAR ;mostra o caracter na tela
      POP DX          ;Retorna o valor inicial para o registrador DL
      RET             ;Retorna o controle ao procedimento que chamou
WRITE_HEX_DIGIT   ENDP
     
	 PUBLIC WRITE_CHAR
;......................................................................;
;Este procedimento imprime um caracter na tela usando uma fun‡�o D.O.S.;
;......................................................................;
WRITE_CHAR   PROC
      PUSH AX   ;Põe na pilha o valor do registrador AX
      MOV AH,2h ;Função 2h
      INT 21h   ;Interrupção 21h
      POP AX    ;Retira da pilha o valor inicial do registrador AX
      RET       ;Retorna o controle ao procedimento que chamou
WRITE_CHAR   ENDP
      END TEST_WRITE_DECIMAL ;finaliza o programa
Este programa mostra na tela os números 12345

 

Quinto exemplo
;nome do programa: five.asm
.model small
.stack
.code
PRINT_ASCII       PROC
      MOV DL,00h       ;move o valor 00h para o registrador DL
      MOV CX,255       ;move o valor decimal 255 para o registrador CX
                       ;usado para fazer um laço com 255 intera‡�es
PRINT_LOOP:
      CALL WRITE_CHAR  ;Chama o procedimento que imprime
      INC DL           ;Incrementa o valor do registrador DL
      LOOP PRINT_LOOP  ;Loop para imprimir 10 caracteres
      MOV AH,4Ch       ;Função 4Ch
      INT 21h          ;Interrupção 21h
PRINT_ASCII       ENDP ;Finaliza o procedimento
WRITE_CHAR      PROC
      MOV AH,2h        ;Função 2h para imprimir um caracter
      INT 21h          ;Imprime o caracter que está em DL
      RET              ;Retorna o controle ao procediemento que chamou
WRITE_CHAR      ENDP   ;Finaliza o procedimento
      END  PRINT_ASCII  ;Finaliza o programa
Este programa mostra na tela o valor dos 256 caracteres do código ASCII.

*****************************************************************************